第四周筆記 c++ Boolan
從這周開始,進入了c++下半部分的學習,這周學習的東西相對之前來說比較瑣碎,但都是值得註意的地方。
一、轉換函數
轉換函數是一種特殊類型的類成員函數。它定義了一個由用戶定義的轉換,以便把一個類對象轉換成某種其他的類型。
在類的聲明中,通過指定關鍵字operator,並在其後加上轉換的目標類型可以來聲明轉換函數,一般格式為:
operator type()
轉換函數的基本規則:
(1)轉換函數只能是成員函數,無返回值,空參數。
(2)不能定義到void的轉換,也不允許轉換成數組或者函數類型。
(3)轉換常定義為const形式,原因是它並不改變數據成員的值。
具體的例子:
class Fraction { public: Fraction(int num, int den) : m_numerator(num), m_denominator(den) {} operator double() const { return (double) (m_numerator / m_denominator); } private: int m_numerator; // 分子 int m_denominator; // 分母 }; Fraction f(3, 5); double d = 4+ f; // 調用operater double將f轉換成double
double d = 4 + f;
這一語句首先查找Fraction是否有重載操作符 operator + (double, Fraction) 的函數,由於沒有,所以會調用轉換函數operator double() const
這裏主要是把 f 轉換成一個double 值。
non-explicit-one-argument constructor
例子:
class Fraction { Fraction(int num, int den=1) : m_numerator(num), m_denominator(den) {} Fractionoperator + (const Fraction& f) { return Fraction(...); } private: int m_numerator; // 分子 int m_denominator; // 分母 }; Fraction f(3, 5); Fraction d2 = f + 4; // 調用non-explicit ctor將4轉換成Fraction(4, 1),然後再調用operator +
構造函數雖然有two parameters(兩個形參),但只有one argument,且構造函數前面沒有explicit,所以叫做non-explicit-one-argument constructor。
這裏主要是通過調用構造函數和通過重載操作符“+”,把4轉換成一個Fraction對象。
conversion function vs. non-explicit-one-argument constructor
class Fraction { Fraction(int num, int den=1) : m_numerator(num), m_denominator(den) {} operator double() const { return (double) (m_numerator / m_denominator); } Fraction operator + (const Fraction& f) { return Fraction(...); } private: int m_numerator; // 分子 int m_denominator; // 分母 }; Fraction f(3, 5); Fraction d2 = f + 4; // [Error] ambiguous
上述的代碼會導致二義性的出現,即 可以將4轉換成Fraction 也可以將f轉換成double,與4相加得到一個double,然後再轉換成Fraction
為了使得編譯通過,可以將Fraction d2 = f + 4;
改成double d2 = f + 4
explicit-one-argument constructor
class Fraction { explicit Fraction(int num, int den=1) : m_numerator(num), m_denominator(den) {} operator double() const { return (double) (m_numerator / m_denominator); } Fraction operator + (const Fraction& f) { return Fraction(...); } private: int m_numerator; // 分子 int m_denominator; // 分母 }; Fraction f(3, 5); Fraction d2 = f + 4; // [Error] convertion from double to Fraction requested
由於在構造函數前面增加了explicit關鍵字,所以不能將4轉換成Fraction類型;也不能先將f轉換成double類型,與4相加後再將double轉換成Fraction。
explicit這個關鍵字基本只出現在構造函數前面,意思是需要明確地需要調用這個構造函數才能調用,不存在暗中、自動的轉換操作。
二、point-like class
(1)智能指針
關於point-like class 的設計,首先,其內必有一真正的指針,並且為了使得智能指針在使用時像正常指針一樣,其設計中必須對操作符 *和->進行重載。
第四周筆記 c++ Boolan