2017-08-02 3 views
0

Dans cette page Web sur le modèle Patten Curlyly Recurring, la classe dérivée peut être instanciée sur la pile (l'exemple Object Counter, dans lequel le modèle de classe de base a un destructeur protégé): CRTP-wiki .. J'ai compilé moi-même.Le destructeur protégé désactive la création des objets de la classe dérivée sur la pile?

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> 
{ 
    // ... 
}; 

Mais cette réponse dit faire la destructor de classe de base protégée interdira instancier classe dérivée sur la pile: answer:

Comme déjà répondu, Poco :: RefCountedObject a protégé destructor, de sorte que toutes les classes héritant de il ne peut être créé sur la pile ....

Ainsi,

(1) est le cette réponse est fausse? Ou ai-je mal compris?

(2) Pourquoi l'exemple CRTP rend-il le destructeur protégé? Est-ce censé interdire l'instanciation d'une spécialisation du modèle de classe de base sur la pile? Puis-je instancier une spécialisation du template de classe de base sur heap (j'ai essayé, je ne peux pas, mais je ne sais pas pourquoi)?

Merci d'avance!

+2

Ne pas lier à des échantillons de code. Les liens meurent. Mettez le code dans la question. Et surtout ne pas lier à des pages qui contiennent beaucoup d'exemples de code qui ne sont pas liés. Est-ce que vous vous attendez vraiment à ce que tout le monde * regarde * ce que vous voulez demander? – StoryTeller

+0

@StoryTeller Merci d'avoir signalé cela et j'ai ajouté le code. Mais s'il vous plait, demandez la prochaine fois :) – user8385554

+3

Eh bien, c'est simple. La réponse que vous avez liée est erronée soit en raison d'une erreur d'écriture ou d'un manque de connaissance. Un destructeur protégé n'empêche pas la création d'objets dervés. – StoryTeller

Répondre

1

J'ai créé un exemple et des objets sur la pile et le tas peuvent être créés. Je pense que la réponse est fausse et que la protection du destructeur a exactement la signification donnée dans le commentaire de votre extrait: "les objets ne devraient jamais être supprimés par des pointeurs de ce type". De plus, 'protected' pourrait être ignoré si des destructeurs étaient rendus virtuels (puisque delete utiliserait toujours le destructeur hérité en premier). J'espère que je n'ai pas manqué quelque chose ici.

#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; 
}