2017-10-17 2 views
0

Salut (l'anglais n'est pas ma langue maternelle, s'il vous plaît me comprendre même si je fais des erreurs! Merci!)Classe de modèle C++, comment déclarer un constructeur de copie pour une situation spécifique?

J'écris une classe de modèle qui peut contenir un pointeur.

template <typename T> 
class SmartPtr { 
private: 
     T value; 
public: 
     SmartPtr() {}; 
     ~SmartPtr() {}; 

    SmartPtr(T* a) 
    { 
     this->value = *a; 
    } 
    SmartPtr(SmartPtr* a) 
    { 
      this->value = a->get_Value(); 
    } 
    SmartPtr(SmartPtr const* a) 
    { 
      this->value = a->get_Value(); 
    } 

    T get_Value()const{ 
      return this->value; 
    } 
}; 

Cette classe est appelée modèle SmartPtr et

class Test 
{ 
public: 
     Test() { std::cout << "Test::Test()" << std::endl; } 

     Test(Test const&) { std::cout << "Test::Test(Test const&)" << std::endl; } 

     ~Test() { std::cout << "Test::~Test()" << std::endl; } 

     Test& operator=(Test const&) 
     { 
      std::cout << "Test& Test::operator=(Test const&)" << std::endl; 
      return *this; 
     } 

     void print() const { std::cout << "Test::print() const" << std::endl; } 
     void print() { std::cout << "Test::print()" << std::endl; } 
}; 

c'est ma classe de test.

Quand je déclare

SmartPtr<Test> ptr_t1 = SmartPtr<Test>(new Test); dans mon main.cpp,

le résultat après la compilation est

Test::Test() 
Test::Test() 
Test& Test::operator=(Test const&) 
Test::~Test() 

mais le résultat que je veux obtenir est

Test::Test() 
Test::~Test() 

Y a-t-il un constructeur de copie de classe de modèle spécifique que j'ai besoin d'écrire Dans cette situation?

Merci beaucoup pour votre patience!

+0

Voir cette question, pas si sûr dupe cependant: https://stackoverflow.com/questions/926752/why-should-i-prefer-to-use-member-initialization-list – Rakete1111

+1

'this-> value = * a; 'est assignation .... – StoryTeller

+0

@StoryTeller Merci pour le commentaire. Désolé, ça fait 10 jours avec C++ et je manque de connaissances. Je ne devrais pas faire une cession? –

Répondre

2

La raison est à cause de l'intérieur SmartPtr il y a la variable membre value:

template <typename T> 
class SmartPtr { 
private: 
     T value; // here T is of class Test 
... other stuff ... 
} 

Lors de la déclaration

SmartPtr<Test> ptr_t1 = SmartPtr<Test>(new Test); 

ptr_t1 est la construction, donc sa valeur est construite. C'est donc le premier appel constructeur Test(). Le deuxième constructeur est le new Test (évidemment). Ensuite, le SmartPtr est construit, et à l'intérieur, le this->value = *a; appelle l'opérateur d'affectation .

Enfin, l'objet SmartPtr<Test>(new Test) est détruit, appelant le destructeur sur l'objet interne value.

Notez également parce qu'il y avait un new Test appelé, mais pas delete, il y a aussi une fuite de mémoire.

+0

une dernière question s'il vous plaît, de sorte que le membre "valeur" devrait être la valeur T * au lieu de la valeur T? –

+0

oui, et le destructeur de SmartPtr devrait «supprimer la valeur» –

+0

Merci pour votre temps. bonne journée! –

0

Pour que le constructeur et destructor à appeler, il suffit d'appeler le constructeur directement:

SmartPtr ptr_t1 (nouveau test);

En outre, votre classe SmartPtr doit stocker un pointeur au lieu de la valeur. La valeur peut résider dans la mémoire allouée par l'appel à new.Au lieu de:

privée: valeur T;

écrire:

privé: T valeur *;

Cela garantira que la valeur est copiée par le constructeur, mais au lieu simplement souligné. La valeur résidera toujours dans la mémoire allouée par new.