The copy constructor is implicitly deleted because the default definition will be poorly formed

I have a class A (from a library that I have no control over) with a private copy constructor and clone , and a class B derived from A I would like to implement clone for B

Naive approach

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

however, a failure because copy constructor A is private:

 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 { 

You can use A::clone() for B::clone() , but I'm not sure how this will work exactly. Any clues?

+7
c ++ copy-constructor clone
source share
3 answers

I assume this is a typo, that your B does not have public members at all, and that you lack public: before defining B::B(int,int) .

The author of the class represented by your A seems to want it to be cloned, but not copied. This suggests that he or she wants everything to live on the heap. But on the contrary, there the public constructor A::A(int) . Are you sure you are right about this?

It is plausible to assume that a class can reveal enough information about a given instance to constitute another instance. For example, a bit more meat on A :

 class A { public: A(int a) : data_(a){}; std::shared_ptr<A> clone() const { return std::shared_ptr<A>(new A(*this)); } int data() const { return data_; } private: A(const A & a) {}; int data_; }; 

And if so, then the public constructor will make it just inconvenient to bypass the private, undefined copy constructor:

 A a0(1); A a1{a0.data()}; // Inconvenient copy construction 

Therefore, I am less sure that A correctly represents the class problem. However, given its meaning, the question you need to answer is: Can you even uncomfortably copy construction A ?

If not, then you're stuck. If so, then you can use the inconvenient copy of building A to explicitly define the normal copy constructor for B that you need. For example.

 class B: public A { public: B(B const & other) : A(other.data()),extraData_(other.extraData_){} B(int data, int extraData): A(data), extraData_(extraData) { } std::shared_ptr<B> clone() const { return std::shared_ptr<B>(new B(*this)); } int extradata() const { return extraData_; } private: int extraData_; }; #include <iostream> int main() { B b(1,2); std::shared_ptr<B> pb = b.clone(); std::cout << pb->data() << std::endl; std::cout << pb->extradata() << std::endl; return 0; } 
+3
source share

You need to make a protective instance of A so that the derived class can use it:

 protected: A(const A & a) { /*...*/ } 

Hope this helps.

+2
source share

The reason that the default definition of copy constructor B is poorly organized is because - if it were allowed to - it would cause a closed (therefore, inaccessible to B ) and undefined copy constructor A

Create copy constructor A either protected or open, so it is available for B Another (very bad) option is to declare class B as a friend of A All features also require that you provide an A copy constructor definition.

+1
source share

All Articles