條款06: 若不想使用編譯器自動生成的函式,就該明確拒絕

博瑜图形發表於2024-09-10

1. 將Copy建構函式或copy Assignment運算子宣告為private
2. 因為member函式和friend函式可以呼叫private函式,不去定義private函式,當呼叫時會獲得一個連結錯誤

class HomeForSale00
{
public:
    HomeForSale00() {}
    void GenerateHomeForSale00Member()
    {
        HomeForSale00 home00;
        HomeForSale00 home01;
        //HomeForSale00 home02(home00); //連結錯誤
        //home00 = home01; //連結錯誤
    }
private:
    friend void GenerateHomeForSale00Friend();
    HomeForSale00(const HomeForSale00&);
    HomeForSale00& operator=(const HomeForSale00&);
private:
    uint32_t HomePrice;
};

void GenerateHomeForSale00Friend()
{
    HomeForSale00 home00;
    HomeForSale00 home01;
    home00.HomePrice = 200;
    //HomeForSale00 home02(home00); //連結錯誤
    //home00 = home01; //連結錯誤
}

void Test00()
{
    HomeForSale00 home00;
    HomeForSale00 home01;
    //HomeForSale00 home02(home00); //private不可訪問
    //home00 = home01; //private 不可訪問

    GenerateHomeForSale00Friend();

    home00.GenerateHomeForSale00Member();
}

1. 為了阻止copying動作設計Uncopyable的base class
2. 因為Uncopyable class不含資料,因此不一定得以public繼承,以及Uncopyable class的解構函式為虛擬函式

class Uncopyable
{
protected:
    Uncopyable() = default;
    ~Uncopyable() = default;
private:
    Uncopyable(const Uncopyable&) = delete;
    Uncopyable& operator=(const Uncopyable&) = delete;
};

class HomeForSale01:private Uncopyable
{
public:
    HomeForSale01() {}
    void GenerateHomeForSale01Member()
    {
        HomeForSale01 home00;
        HomeForSale01 home01;
        //HomeForSale01 home02(home00); //連結錯誤
        //home00 = home01; //連結錯誤
    }
private:
    friend void GenerateHomeForSale01Friend();
    HomeForSale01(const HomeForSale01&);
    HomeForSale01& operator=(const HomeForSale01&);
private:
    uint32_t HomePrice;
};

void GenerateHomeForSale01Friend()
{
    HomeForSale01 home00;
    HomeForSale01 home01;
    home00.HomePrice = 200;
    //HomeForSale01 home02(home00); //連結錯誤
    //home00 = home01; //連結錯誤
}

void Test01()
{
    HomeForSale01 home00;
    HomeForSale01 home01;
    //HomeForSale01 home02(home00); //private不可訪問
    //home00 = home01; //private 不可訪問

    GenerateHomeForSale01Friend();

    home00.GenerateHomeForSale01Member();
}

int main()
{
    Test00();
    Test01();
    return EXIT_SUCCESS;
}

相關文章