對於C++友元函數,我在這麼多年的C++編程中用得最多的場合就是重載雙目運算符的時候。每次定義一個新的雙目運算符就自然而然的會想起它來。
用之,會有什麼好處;
不用,又會如何呢?
先看看不用的情況,是如何定義一個雙目運算符的。
class MyString { public: MyString(char* s) : m_data(NULL) { delete m_data; m_data = new char[100]; strcpy(m_data, s); } // 在成員函數中重載運算符 MyString operator+(const MyString& rhs) { MyString s(""); strcat(s.m_data, m_data); strcat(s.m_data, rhs.m_data); return s; } private: char* m_data; };那麼,使用的結果是:
MyString s("ABC"); MyString s1 = s + "abc"; // OK MyString s2 = "abc" + s; // 報錯!!!由於定義為類的成員變量,所以只能在第二個參數做構造函數的隱式轉換。一旦參數調換個順序,立馬報錯。所以這種方式不適合自然語言的描述,使用起來局限性就大了。
然而,通過友元函數的定義方式可以很好的解決這個問題。
class MyString { public: MyString(char* s) : m_data(NULL) { delete m_data; m_data = new char[100]; strcpy(m_data, s); } // 定義為友元函數 friend MyString operator+(const MyString& s1, const MyString& s2); private: char* m_data; }; MyString operator+(const MyString& s1, const MyString& s2) { MyString s(""); strcat(s.m_data, s1.m_data); strcat(s.m_data, s2.m_data); return s; }那麼,兩種方式的調用都暢通無阻了!
MyString s("ABC"); MyString s1 = s + "abc"; // OK MyString s2 = "abc" + s; // OK