1. 程式人生 > >第四周筆記 c++ Boolan

第四周筆記 c++ Boolan

action 分享圖片 bool 規則 類的聲明 one amp public 函數類型

從這周開始,進入了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) {}

    Fraction 
operator + (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