高效C++:模板和泛型編程

模板和泛型編程的關注重點在編譯期,所有的行爲都在編譯期確定,因此其規則和玩法也有自己特殊的一套,和其他模塊不通用。

 

瞭解隱式接口和編譯期多態

 

瞭解typename的雙重含義

  • 聲明template參數時,前綴關鍵字class和typename可以互換

  • 使用typename關鍵字聲明嵌套從屬類型名稱,但不可以出現在基類列表和初始化裏列表中

  • 嵌套從屬名稱

複製代碼

template<typename C>
void Print2Nd(const C& container)
{
    ...
   typename C::const_iterator iter(container.begin()) //確認是類型不是名稱
    ...    
}

//C::const_iterato 從屬嵌套類型(名稱中依賴於template類型參數)

複製代碼

 

學習處理模板化基類內的名稱

  • 在Derived class template中調用base class template的函數時,直接調用編譯不過,可以使用如下方法:

    • this->xxx (建議)

    • basename::xxx

    • using basename::xxx

複製代碼

class CompanyA{
public:
    CompanyA(){}

    void Send()
    {
        cout<<"CompanyA::Send()"<<endl;
    }
};

class CompanyB{
public:
    CompanyB(){}

    void Send()
    {
        cout<<"CompanyB::Send()"<<endl;
    }
};

template<typename Company>
class Sender{
public:
    Sender(){}
    
    void SendMsg()
    {
        Company c;
        c.Send();
    }
};


template<typename Company>
class LogSender: public Sender<Company>
{
public:
    using Sender<Company>::SendMsg;  

    void LogSendMsg()
    {
        cout<<"LogSender::LogSendMsg() before"<<endl;
        
        SendMsg();  //單獨使用錯誤,配合using使用ok
        this->SendMsg(); //OK
        Sender<Company>::SendMsg(); //OK
        
        cout<<"LogSender::LogSendMsg() after"<<endl;
    }

};

複製代碼

 

將與參數無關的代碼抽取template

  • 不要將函數參數提取爲template,這樣導致代碼冗餘

 

運用成員函數模板接受所有兼容類型

  • 使用模板成員函數生成可接受和兼容所有類型的函數,包括構造函數

複製代碼

template<typename U>
class A
{
public:    
    template<typename T>
    A(A<T>& other)
    {
        ...
    }
};

複製代碼

  • 如果將構造函數聲明爲模板函數,爲了阻止編譯器生成默認的構造函數,你必須明確聲明一個非模板的構造函數

 

需要類型轉換時請爲模板定義非成員函數

  • template在推倒慮隱式轉換

  • 對比“定義no-member函數進行類型轉換”這一條規則

複製代碼

template<typename T>
const Rational<T> doMutliply(const Rational<T>& lhs, const Rational<T>& rhs)
{
    ...
}

template<typename T>
class Rational
{
public:
    ...
    //聲明爲friend函數的目的是tempalte推倒,保證編譯通過,根本目的是提供一個使用是所有類型的乘法   
    frined const Rational<T>operator*(const Rational<T>& lhs, const Rational<T>& rhs)
    {
        return doMutliply(lhs, rhs);
    } 
}

複製代碼

 

請使用traits classes表現類型信息

  • 需要了解STL編程,可以參考《STL源碼剖析》一書

  • 運用到模板、元編程等知識

 

瞭解template元編程

  • 元編程將運行期的工程提前到編譯期,錯誤的發現更早,效率更高

 

分類: C++

標籤: 泛型編程 模板

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章