重載operator[]符號
tags: C++ Concept
解決必須重複打兩次的問題
重載下標[]符號
如果一個類別的屬性是帶 const 屬性,那麼他將會呼叫 const 版本的
const Arr a(5);
const int & operator[](size_t idx) const{...}
即便不使用到帶const屬性的類別宣告
仍然有可能在重載運算符號時用上(待確認印象中記得會)
仍然有可能在重載運算符號時用上(待確認印象中記得會)
Arr a(5), b(5);
a=a+b;
你就必須寫兩份重載函式
const int & operator[](size_t idx) const{...}
int & operator[](size_t idx){...}
除非確定了,不然還是乖乖補上兩種代碼可能比較省事。
這時候就產生一個問題,代碼可能需要寫兩次,至直接導致修改時要改兩處,麻煩了不少。
參考代碼
/*****************************************************************
Name : 重載下標符號 const 函式
Date : 2017/02/20
By : CharlotteHonG
Final: 2017/02/20
*****************************************************************/
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
class Arr{
public:
// 建構子
Arr(int len): arr(len){
iota(arr.begin(),arr.end(),1);
}
// 重載下標符號
int & operator[](size_t idx){
cout << "**Non_";
return const_cast<int&>(static_cast<const Arr&>(*this)[idx]);
}
const int & operator[](size_t idx) const{
cout << "**Const**" << endl;
return arr[idx];
}
private:
vector<int> arr;
};
int main(int argc, char const *argv[]){
// **Const**
const Arr ca(5);
cout << ca[0] << endl;
// **Non-Const**
Arr a(5);
cout << a[0] << endl;
return 0;
}
原理
讓 非const版本 的強制去呼叫 const版本的static_cast<const class&>(*this)
然後再強制解除 const 屬性const_cast<typename&>
就可以整合成一份主代碼了
是否可以反過來
實際上也是可以把主代碼寫在非const上,語法的運行是可以的,但這會有一種問題,由const呼叫非const貌似有些奇怪:
都已經限制不能修改了,你還去呼叫可以修改的?
也可以換一個角度想,在強制呼叫非const版本的時候,的這個瞬間所返回的參考所參考之處是可以被修改的,const版本的函式居然會有可能被修改,這不符合const的定義。
為避免這不必要的疑慮,應該由非const版本呼叫const版本,避開這些疑慮
/*****************************************************************
Name : 重載下標符號 const 函式
Date : 2017/02/20
By : CharlotteHonG
Final: 2017/03/17
*****************************************************************/
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
class Arr{
public:
// 建構子
Arr(int len): arr(len){
iota(arr.begin(),arr.end(),1);
}
// 重載下標符號
int & operator[](size_t idx){
cout << "Non";
// return const_cast<int&>(static_cast<const Arr&>(*this)[idx]);
return arr[idx];
}
const int & operator[](size_t idx) const{
cout << "Const";
// return arr[idx];
return static_cast<const int&>(const_cast<Arr&>(*this)[idx]);
}
private:
vector<int> arr;
};
int main(int argc, char const *argv[]){
// **Const**
const Arr ca(5);
cout << " = " << ca[0] << endl;
// **Non-Const**
Arr a(5);
cout << " = " << a[0] << endl;
return 0;
}
參考
ilikekotomi:參考Scott Meyers的Effective C++ 3rd的第三條款
沒有留言:
張貼留言