為什麼c++不能把「= [] () ->」操作符重載為非成員函數?
我查了一下stackoverflow,大家對於不能把『=』重載為非成員函數的理由主要是因為如果類內未重載『=』操作符,則編譯器會自動合成一個默認的『=』操作符,如果在類外再定義會產生二義性
c++ - Why can"t we overload "=" using friend function?c++ - Why cannot a non-member function be used for overloading the assignment operator?但是現在有兩個問題,1.為什麼會產生二義性?編譯器所自動合成的默認"="操作符無非是 T operator=(const T)這個樣子的函數,那麼如果我在類外定義一個T operator=(const T, int)這樣的函數,會有二義性嗎?我用『+』操作符做了這個實驗,並沒有出現任何問題:
class foo{
public:
void operator+(const foo tmp){
cout &<&< "member-function" &<&< endl; } }; void operator+(const foo tmp, int i) { cout &<&< "unmember-function" &<&< endl; } int main(int argc, char* argv[]) { foo test; foo test2; test + test2; test + 1; system("pause"); return 0; }輸出為
「member-function」
「unmember-function」2. 第二個問題是,怎麼解釋[] -&> ()這三個也不能定義為非成員操作符?
其實把這些操作符弄成非成員函數沒有問題,只不過這些非成員函數能做到的事情成員函數都能做到(operator()和[]除外)。所以允許這些操作符成為非成員函數並不會讓你更加方便地寫代碼。
《C++設計與演化》中提到
如果operator=是全局的,那麼在某些文件中聲明了operator=某些文件沒有聲明,那麼就造成了在不同文件中operator=行為不一致的問題。
至於() -&> [] 書中沒有明確說明,看樣子也是擔心全局的話會造成行為不一致的問題。換個思路。
如果=, (), -&>和[]能重載為非成員函數,那麼是不是我可以重載operator=(int, T),然後就修改了默認的int賦值語義了?
然後你所有的涉及到int賦值的代碼都會變成一坨屎。
就是這樣。
Operator[] overloading using friend function
As Bjarne Stroustrup says in the Damp;E book:
However, even in the original design of C++, I restricted operators [], (), and -&> to be members. It seemed a harmless restriction that eliminated the possibility of some obscure errors because these operators invariably depend on and typically modify the state of their left-hand operand. However, it is probably a case of unnecessary nannyism
這些話解釋的挺好的
你看這樣理解對不對因為每個類都隱式地有這幾個運算符的定義,所以全局函數會被隱式的函數覆蓋掉,而像+這些符號因為本身沒有定義,所以聲明為全局函數和成員函數是一樣的
class foo{
public:
void operator+(const foo tmp){
cout &<&< "member-function" &<&< endl;
}
};
void operator+(const foo tmp, const foo tmp1)
{
cout &<&< "unmember-function" &<&< endl;
}
int main(int argc, char* argv[])
{
foo test;
foo test2;
test + test2;
//調用成員函數版operator=
system("pause");
return 0;
}
類賦值操作符必須是類的成員,以便編譯器可以知道是否需要合成一個~
直觀上就是這樣的。對象自己的行為,對象自己決定。難道你要在外面訪問對象的各種信息?有點品味好不
推薦閱讀:
※為什麼這些年c語言統治了幾乎所有方面?
※怎麼理解 `auto var = [&]() { /* things to do */ }`?
※為什麼 C++ 列表初始化時會執行兩次拷貝構造函數?
※寫循環語句,循環體部分理論上是不是可以都寫在for(;;)第二個分號後?
※map key是一個複雜結構,為什麼無法插入?
TAG:C |