日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

C++設(shè)計與聲明超詳細(xì)講解_C 語言

作者:RolleX ? 更新時間: 2022-11-14 編程語言

讓接口被正確使用不易被誤用

除非有好的理由,否則應(yīng)該讓你的types的行為與內(nèi)置types一致,請拿ints做范本

提供行為一致的接口!

阻止誤用的辦法包括建立新類型,限制類型上的操作,束縛對象值(比如要統(tǒng)計年月日,限制月的大小在1-12),消除客戶的資源管理責(zé)任(智能指針)

shared_ptr支持定制型刪除器,可被用來自動解除互斥鎖等

寧以pass-by-reference-to-const替換pass-by-value

值傳遞要調(diào)用copy構(gòu)造函數(shù),釋放時要調(diào)用多次析構(gòu)函數(shù)(有副本),費時

const的必要性:引用傳遞代替值傳遞時,確保不會對傳入的數(shù)據(jù)做改變

防止被切割:

class Window{
public:
    virtual void display();
}
class WindowWithScrollBars:public Window{
public:
    virtual void display();
}
void show(Window w){
    w.display();
}

當(dāng)用一個WindowWithScrollBars對象傳入show時,因為是值傳遞,會導(dǎo)致其特化信息被切割,變成了一個Window對象!無法多態(tài)了!

應(yīng)該如下:傳進(jìn)來的窗口是什么類型,w就表現(xiàn)出哪種特性

void show(const Window& w){
    ...
}

說到底,引用是指針實現(xiàn)出來的,引用傳遞說到底也是傳遞的指針,如果有一個對象屬于內(nèi)置類型,值傳遞效率會比引用傳遞效率高一些。

值傳遞對于內(nèi)置類型和STL的迭代器和函數(shù)對象來說代價不貴,其他類型還是選用const引用傳遞好!

必須返回對象時

別妄想返回reference

不是所有情況都是引用傳遞好

const A& operator*(const A& rhs){
    A result(rhs);//調(diào)用構(gòu)造函數(shù)
    return result; 
}

返回了一個result的引用,但result是一個局部變量,離開作用域就被析構(gòu)了!!!

引用不能返回一個局部對象,否則一敗涂地

一個必須返回新對象的函數(shù)的做法是:就讓他返回一個新對象唄

const A operator*(const A& rhs){
    A result(rhs);//調(diào)用構(gòu)造函數(shù)
    return A(rhs); 
}

承受一個operator*構(gòu)造和析構(gòu)函數(shù)的代價即可

絕對不要返回一個指針或引用指向一個local stack對象(出作用域會被析構(gòu)),或返回引用指向一個heap-allocated對象(無法保證合理的delete),或返回指針或引用指向一個local static對象而有可能同時需要多個這樣的對象(一個指針修改了指向?qū)ο蟮膮?shù)后,其他指針指向的參數(shù)也被修改了)

將成員變量聲明為private

語法一致性:成員變量不是public,用戶只能通過public里的相應(yīng)函數(shù)來訪問成員變量,用戶使用時就都有一致的使用規(guī)則(全都要使用小括號等)

使用函數(shù)可以對成員變量的處理有更精確的控制,如可以編寫const函數(shù)實現(xiàn)只讀訪問,不加const實現(xiàn)讀寫訪問等

封裝性,防止成員變量被更改

假如有一個public成員變量,我們最終取消了它,所有使用它的代碼都會被破壞,假如有一個protected成員變量,我們最終取消了它,所有使用它的派生類都會被破壞。因此protected其實并不比public更加具有封裝性

說到底,選擇private就好

以non-member non-friend替換member函數(shù)

能夠訪問private成員變量的函數(shù)只有class的member函數(shù)加上friend函數(shù),如果要在一個member函數(shù)(不只可以訪問private數(shù)據(jù),也能取用private函數(shù)、enums、typedefs等)和一個non-member,non-friend函數(shù)做抉擇,較好封裝性的時后者。因為它并不增加能夠訪問class內(nèi)private成分的函數(shù)數(shù)量

將所有便利函數(shù)放在多個頭文件內(nèi)但同屬于一個命名空間,用戶可以輕松添加這一組便利函數(shù),即可以添加更多的non-member,non-friend函數(shù)到此命名空間

參考C++標(biāo)準(zhǔn)程序庫,vector、algorithm等,導(dǎo)入頭文件再進(jìn)行調(diào)用,即可完成很多事情

non-member

若所有參數(shù)皆需要類型轉(zhuǎn)換,請為此采用non-member函數(shù)

class Rational{
public:
    Rational(int numerator=0,int denominator=1);
    int numerator() const;
    int denominator() const;
    const Rational operator* (const Rational& rhs) const;
}
Rational onehalf(1,2);
Rational result=onehalf*2;//很好!
Rational result=2*onehalf;//不行!

原因在于:

result=onehalf.operator*(2);//發(fā)生了隱式轉(zhuǎn)換 得益于之前沒有將構(gòu)造函數(shù)聲明為explicit
result=2.operator*(onehalf);

2沒有相應(yīng)的class,沒有operator*成員函數(shù),當(dāng)然無法執(zhí)行

結(jié)論為:只有當(dāng)參數(shù)被列于參數(shù)列內(nèi),這個參數(shù)才是隱式轉(zhuǎn)換的合格參與者

改變做法為將operator*變成non-member函數(shù),允許編譯器在每個實參上執(zhí)行隱式轉(zhuǎn)換

operator*是否應(yīng)該成為class的一個friend函數(shù)呢?否定的,因為operator*完全可以借用Rational的public接口完成任務(wù),這告訴我們:member函數(shù)的反面是non-member,而不是friend

如果你需要為某個函數(shù)的所有參數(shù)(包括this指針?biāo)傅哪莻€隱喻參數(shù))進(jìn)行類型轉(zhuǎn)換,那么這個函數(shù)必須是non-member

考慮寫出一個不拋出異常的swap函數(shù)

當(dāng)做swap時,如果交換內(nèi)部的指針,效率就高了呀

以指針指向一個對象,內(nèi)含真正的數(shù)據(jù),即pimpl手法(pointer to implementation)

class WidgetImpl{
public:
    ...
private:
    int a,b,c;
}
class Widget{
public:
    void swap(Wideget& other){
        using std::swap;//必要的,在找不到class里的swap函數(shù)調(diào)用此函數(shù)
        swap(p,other.p);
    }
private:
    WidgetImpl* p;
}
//修訂后的std::swap特化版本
namespace std{
    template<>
    void swap<Widget>(Widget& a,Widget& b)
    {
        a.swap(b);//調(diào)用a的swap成員函數(shù)
    }
}

這種方法和STL有一致性,因為STL也提供有public的成員函數(shù)和std::swap的特化版本

如果swap的默認(rèn)版本的效率你可以接受,那不需要做任何事

如果swap的默認(rèn)版本實現(xiàn)效率不足:

1、提供一個public swap成員函數(shù),讓它高效的置換兩個對象(pimpl)

2、在class的命名空間內(nèi)提供一個non-member swap,并用它調(diào)用上訴swap成員函數(shù)。

3、如果正在編寫一個class,為class特化std::swap,并用它調(diào)用你的swap成員函數(shù)。

原文鏈接:https://blog.csdn.net/RolleX/article/details/126982795

欄目分類
最近更新