Effective C++条項43

5950 ワード

学習処理テンプレート化ベースクラスの名前
このセクションの著者が作成した意図は、「テンプレートクラスに関する派生プロセスをどのように定義し、使用するか、派生プロセスに発生するコンパイル不通過問題をどのように処理するか」ということです.
次に、説明的なコードを見てみましょう.
#include<iostream>
using namespace std;

class object1
{
public:
    void get(){ cout << "object1"; }
    void out(){ cout << "out1"; }
};


class object2
{
public:
    void get(){ cout << "object2"; }
    void out(){ cout << "out2"; }
};

template <typename object>
class A
{
public :
    void func1()
    {
        object ob;
        ob.get();
    }
    void func2()
    {
        object ob;
        ob.out();
    }
};

int main()
{
    A<object1>a;
    a.func1();//  object1  get  
    cout << endl;
    A<object2>b;
    b.func2();//  object2  out  


}

上記のコードからtemplateテンプレートがプログラミングの優位性をもたらし、コードの利用率を大幅に向上させることがわかります.しかし、パフォーマンスの背後には、多重継承におけるコンパイルの問題など、いくつかの犠牲があることが多い.次のコードがあります.
#include<iostream>
using namespace std;

class object1
{
public:
    void get(){ cout << "object1"; }
    void out(){ cout << "out1"; }
};


class object2
{
public:
    void get(){ cout << "object2"; }
    void out(){ cout << "out2"; }
};

class object3
{
public:
    void out(){ cout << "out3"; }
};



template <typename object>
class A
{
public :
    void func1()
    {
        object ob;
        ob.get();
    }
    void func2()
    {
        object ob;
        ob.out();
    }
};

template<> 
class A<object3>
{
public:
    void func2()
    {
        object3 ob;
        ob.out();
    }
};

template <typename object>
class B:public A<object>
{
public:
    void func3()
    {
        func1();
    }
};

以上のコードは、テンプレートクラスtemplate base classにfunct 1()関数があるかどうかを判断できないため、著者の意味でコンパイルは通過しません.vs 2014エディタを使用していますが、このような問題は発生していません.だから、マイクロソフト開発大神がこのコンパイルの欠点を改善したのではないか.一言で言えば、vs 2014にとってこの条項は無効で、大神の指摘を歓迎します.さらに,なぜコンパイルできないのかというと,フル特化テンプレートの出現があるからである.以上のようにobject 3のフル特化中にfunct 1()関数がない場合,コンパイラがブロックしなければプログラム以降の実行中にクラッシュする.
著者の意思では,以上の問題が発生した場合,以下の3つの手段で解決できるが,3つの方法の意図は,ベースクラスに派生クラスを持つために必要な関数をコンパイラに伝えることである.コンパイラをベースクラスに入れて探します.探していない前提で新聞をコンパイルするのではなく、間違っています.1つ目:
template <typename object>
class B:public A<object>
{
public:
    void func3()
    {
        this->func1();//  this   
    }
};

2つ目:
template <typename object>
class B:public A<object>
{
      using A<object>::func1;
public:
    void func3()
    {
        this->func1();//  this   
    }
};

3つ目:
template <typename object>
class B:public A<object>
{
public:
    void func3()
    {
        A<object>::func1();
    }
};

3つ目はvirtualバインド動作を閉じ、慎重に使用します.