operator=() 進階重載,具2種或多種語意重載
tags: C++ Concept
除了一般重載等號之外,如果你想做不同的操作,比如說你希望在指定單一元素的時候可以用等號做存取
Raw a(4, 4);
假設這是一張4x4總共16格的一維陣列
a[0] = -1;
你可以透過下標的等號直接存取
a.at2d(0, 1) = -1;
也可以透過函式進行二維模式的存取
// 區塊等號賦值
a.blk(2) = a.blk(3);
甚至可以在不影響原本運算子的情況下進型區塊複製
區塊指的是以4個單位為一組計算,全部16個可以分成4組
最左上4個為0,最右下4個為3
區塊指的是以4個單位為一組計算,全部16個可以分成4組
最左上4個為0,最右下4個為3
// 不影響原本的等號
Raw b(4, 4);
a=b;
仍然是預設複製運算子,複製所有資源
用途
這在某些複雜的運算上,可以很大的程度的減少代碼量與程式設計難度
只不過效能上可能多少有些損耗。
只不過效能上可能多少有些損耗。
參考代碼:
/*****************************************************************
Name :
Date : 2017/03/21
By : CharlotteHonG
Final: 2017/03/21
*****************************************************************/
#include <iostream>
#include <iomanip>
#include <vector>
#include <numeric>
#include <cmath>
#include <typeinfo>
using namespace std;
class Raw {
public:
Raw(size_t y, size_t x): col(x), img(y*x){
iota(img.begin(), img.end(), 1);
}
public: // 運算子
// 重載下標符號
int & operator[](size_t idx){
return const_cast<int&>(static_cast<const Raw&>(*this)[idx]);
}
const int & operator[](size_t idx) const{
return img[idx];
}
int & at2d(size_t y, size_t x){
return const_cast<int&>(
static_cast<const Raw&>(*this).at2d(y, x));
}
const int & at2d(size_t y, size_t x) const{
return (*this)[y*col+x];
}
public: // 基礎函式
void info(){
for(unsigned j = 0; j < img.size()/col; ++j) {
for(unsigned i = 0; i < col; ++i) {
cout << setw(3) << img[j*col+i];
}cout << endl;
}cout << endl;
}
void get_block(size_t h, size_t w);
private:// 資料成員
size_t col;
vector<int> img;
private:
class Block;
vector<Block> blk_p;
public:
Block blk(size_t pos);
};
// 轉介的類別
class Raw::Block{
public:
#define BlkSize 4 // 區塊大小
Block(): p(BlkSize){}
Block(Raw & img, size_t pos): p(BlkSize){
size_t Sidelen = sqrt(BlkSize);
// 取得對應位置
size_t pos_y=((pos/((img.img.size())/img.col/Sidelen))*Sidelen);
size_t pos_x=((pos%(img.col/Sidelen))*Sidelen);
// 複製指標
for(unsigned j=0, c=0; j < Sidelen; ++j)
for(unsigned i = 0; i < Sidelen; ++i, ++c)
p[c] = &img.at2d(pos_y+j, pos_x+i);
}
// 深層拷貝
Block & operator=(Block const & rhs){
cout << "C &" << endl;
if (this == &rhs)
return (*this);
for (unsigned i = 0; i < p.size(); ++i)
*(p[i]) = *(rhs.p[i]);
return (*this);
}
// 淺層拷貝
Block & copy(Block const & rhs){
if (this == &rhs){
return (*this);
} else {
p = rhs.p;
} return (*this);
}
Block & copy(Block && rhs){
if (this == &rhs){
return (*this);
} else {
p = std::move(rhs.p);
} return (*this);
}
void info(){
for(auto&& i : p) {
cout << setw(3) << *i ;
}cout << endl;
}
public:
vector<int*> p;
};
auto Raw::blk(size_t pos)-> Block{
return Block((*this), pos);
}
void Raw::get_block(size_t h=2, size_t w=2){
size_t len = (img.size()/col/h) * (col/w);
// cout << "len=" << len << endl;
this->blk_p.resize(len);
// blk_p 預載 len 個區塊
for (unsigned i = 0; i < len; ++i){
this->blk_p[i].copy( Block((*this), i) );
// this->blk_p[i].info();
}
}
/*==============================================================*/
int main(int argc, char const *argv[]){
Raw a(4, 4);
a.info();
// 一般等號賦值
a[0] = -1;
a.at2d(0, 1) = -1;
a.info();
// 區塊等號賦值
a.blk(2) = a.blk(3);
a.info();
return 0;
}
/*==============================================================*/
沒有留言:
張貼留言