I've got a class A (from a library over which I have no control) with a private copy constructor and a clone method, and a class B derived from A. I would like to implement clone for B as well.
The 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, fails, since the copy constructor of 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 {
There might a way to make use of A::clone() for B::clone(), but I'm not sure how this would work exactly. Any hints?
I presume it's a typo that your
Bhas no public members at all, and that you're missing apublic:before the definition ofB::B(int,int).The author of the class represented by your
Aapparently wants it to be cloneable but not copy constructible. That would suggest he or she wants all instances to live on the heap. But contrariwise, there's the public constructorA::A(int). Are you sure you are right about that?It's plausible to suppose that the class can reveal enough information about a given instance to constitute another instance. E.g., putting a little more flesh on
A:And if that is true, then the public constructor would render it merely inconvenient to circumvent the private, undefined copy constructor:
So I'm less than confident that
Afaithfully represents the problem class. Taking it at face value, however, the question you need to answer is: Can you even inconveniently copy construct anA?If not then you're stuck. If so, then you can use inconvenient copy construction of
Ato expressly define a conventional copy constructor forB, which is all you need. E.g.