2017-08-02 5 views
0

Curiously Recurring Template PattenについてのこのWebページでは、派生クラスをスタック上にインスタンス化することができます(オブジェクトカウンターの例、基本クラステンプレートに保護されたデストラクターがあります)。CRTP-wiki ..私は自分自身をコンパイルしました。プロテクトされたデストラクタは、スタック上の派生クラスのオブジェクトの作成を無効にしますか?

template <typename T> 
struct counter 
{ 
    static int objects_created; 
    static int objects_alive; 

    counter() 
    { 
     ++objects_created; 
     ++objects_alive; 
    } 

    counter(const counter&) 
    { 
     ++objects_created; 
     ++objects_alive; 
    } 
protected: 
    ~counter() // objects should never be removed through pointers of this type 
    { 
     --objects_alive; 
    } 
}; 
template <typename T> int counter<T>::objects_created(0); 
template <typename T> int counter<T>::objects_alive(0); 

class X : counter<X> 
{ 
    // ... 
}; 

class Y : counter<Y> 
{ 
    // ... 
}; 

しかし、この答えは保護された基本クラスのデストラクタがスタックに派生クラスをインスタンス化禁止します作ると言う:answer

としては、ポコ:: RefCountedObjectはので、すべてのクラスから継承し、デストラクタを保護していた、すでに答えそれはスタック上に作成することはできません....

ので、

は、(1)でありますこの答えは間違っている?それとも私は誤解しましたか?

(2)なぜCRTPの例では、デストラクタを保護していますか?それは、スタック上の基本クラステンプレートの特殊化をインスタンス化することを禁止することを意図していますか?ヒープ上の基本クラステンプレートの特殊化をインスタンス化できますか(私は試しましたが、できませんが、理由はわかりません)。

ありがとうございます!

+2

コードサンプルにリンクしないでください。リンクは死ぬ。コードを質問に入れてください。また、無関係なコードサンプルが多数含まれているページには特にリンクしないでください。あなたは本当に誰もがあなたが尋ねたいことを誰かが見るように見ていますか? – StoryTeller

+0

@StoryTellerこれを指摘してくれてありがとう、ありがとう、コードを追加しました。しかし、次回にうまくお願いしてください:) – user8385554

+3

まあ、簡単です。あなたが書いたミスや知識の不足のためにあなたが結んだ答えは間違っています。保護されたデストラクタは、壊れたオブジェクトの作成を防ぎません。 – StoryTeller

答えて

1

サンプルを作成しました。スタックとヒープの両方のオブジェクトを作成できます。 私は答えが間違っていると思うし、デストラクターを保護することはあなたのスニペットでコメントに与えられた意味を正確に持っています: "オブジェクトはこのタイプのポインタを通して決して削除すべきではありません"。また、デストラクタが仮想化されている場合(deleteは常に継承されたデストラクタを最初に呼び出すため)、 'protected'をスキップすることができます。私はここで何かを逃さないことを願っています。

#include <cstdio> 

template <typename T> 
struct counter 
{ 
    static int objects_created; 
    static int objects_alive; 

    counter() 
    { 
     ++objects_created; 
     ++objects_alive; 
    } 

    counter(const counter&) 
    { 
     ++objects_created; 
     ++objects_alive; 
    } 
protected: 
    ~counter() // objects should never be removed through pointers of this type 
    { 
     --objects_alive; 
    } 
}; 
template <typename T> int counter<T>::objects_created(0); 
template <typename T> int counter<T>::objects_alive(0); 

class X : counter<X> 
{ 
public: 
    X() 
    { 
     printf("Hello from X %dth instance, %d still up\n", objects_created, objects_alive); 
    } 

    ~X() 
    { 
     printf("Bye X\n"); 
    } 
}; 

int main() 
{ 
    { 
     X x; // hello x1 
     { 
      X x2; // hello x2 
     } // bye x2 

     X* x3 = new X(); // hello x3 
     X* x4 = new X(); // hello x4 

     delete x3; // bye x3 

     counter<X>* x5 = (counter<X>*)x4; 

     delete x5; // destructor is inaccesible, does not compile 
    } 
    return 0; 
} 
関連する問題