constructeur de copie est implicitement supprimé parce que la définition par défaut serait mal formé
J'ai une classe A
(à partir d'une bibliothèque sur laquelle je n'ai aucun contrôle) avec un constructeur de copie et un clone
méthode, et une classe B
dérivé de A
. Je tiens à mettre en œuvre clone
pour B
ainsi.
L'approche naïve
#include <memory>
class A { //I have no control here
public:
A(int a) {};
std::shared_ptr<A>
clone() const
{
return std::shared_ptr<A>(new A(*this));
}
private:
A(const A & a) {};
};
class B: public A {
public:
B(int data, int extraData):
A(data),
extraData_(extraData)
{
}
std::shared_ptr<B>
clone() const
{
return std::shared_ptr<B>(new B(*this));
}
private:
int extraData_;
};
int main() {
A a(1);
}
cependant, ne parvient pas, depuis le constructeur de copie de A
est privé:
main.cpp: In member function ‘std::shared_ptr<B> B::clone() const’:
main.cpp:27:42: error: use of deleted function ‘B::B(const B&)’
return std::shared_ptr<B>(new B(*this));
^
main.cpp:17:7: note: ‘B::B(const B&)’ is implicitly deleted because the default definition would be ill-formed:
class B: public A {
^
main.cpp:14:5: error: ‘A::A(const A&)’ is private
A(const A & a) {};
^
main.cpp:17:7: error: within this context
class B: public A {
Il pourrait y un moyen de rendre l'utilisation de A::clone()
pour B::clone()
, mais je ne suis pas sûr de savoir comment cela fonctionnerait exactement. Un indice?
Vous devez vous connecter pour publier un commentaire.
Je présume que c'est une faute de frappe que votre
B
n'a pas de membres du public à tous,et que vous êtes absent une
public:
avant la définition deB::B(int,int)
.L'auteur de la classe représentée par votre
A
veut apparemment à êtreclonable, mais pas de copie constructible. Qui laisserait à penser qu'il ou elle veut que tous les
les instances de vivre sur le tas. Mais, au contraire, il y a le public
constructeur
A::A(int)
. Êtes-vous sûr que vous avez raison à ce sujet?Il est plausible de supposer que la classe peut révéler assez d'informations
sur une instance donnée constituent un autre exemple. E. g., mettre
un peu plus de chair sur
A
:Et si cela est vrai, alors le constructeur public rendrait simplement
pas pratique pour contourner le privé, undefined constructeur de copie:
Donc je suis moins certain que
A
représente fidèlement le problèmeclasse. En le prenant à la valeur nominale, cependant, la question que vous devez répondre
est: Pouvez-vous encore malencontreusement copie de construire un
A
?Si non, alors vous êtes coincé. Si oui, alors vous pouvez utiliser dérange copie
la construction de
A
expressément définir un classique de constructeur de copie pourB
,ce qui est tout ce dont vous avez besoin. E. g.
Vous avez besoin de faire le constructeur par copie de
A
protégés de façon à ce que la classe dérivée peut l'utiliser:Espère que ça aide.
A
puisqu'il provient d'une bibliothèque; j'ai expliqué cela dans le post original.A
.A
. Vous devez utiliser la composition maintenant, au lieu de l'héritage.A
à tous. Avoir un (et omis) constructeur de copie est un assez gros soupçon de la part du développeur que de choses diverses - y compris à l'aide deA
comme une classe de base - sont découragés.La raison pour laquelle la définition par défaut de
B
s'constructeur de copie est mal formé est parce que - si elle était autorisée - elle invoque le privé (donc inaccessible àB
) et n'est pas définie constructeur de copie deA
.Faire
A
s'constructeur de copie soit protégé ou public, de sorte qu'il est accessible àB
. Un autre (très mauvais) option consiste à déclarer la classeB
comme un ami deA
. Toutes les possibilités sont également vous demander de fournir une définition pourA
s'constructeur de copie.A
.A::clone()
soit?