Auto-cloning unique_ptr - c++

std::unique_ptr has a deleted copy constructor, which means that if you have a unique_ptr in your class Foo as a data member then you must write your own copy constructor for Foo and manually deep-copy that member (even if the compiler-generated copy constructor would be fine for all other members).
In order to be able to copy in a polymorphic way, the clone() method pattern can be used. Let's assume our objects have a clone method like this:
class Base {
virtual std::unique_ptr<Base> clone() = 0;
};
Foo looks like this now:
class Foo {
public:
...
Foo(Foo const& other)
: b(other.b->clone())
, // init 10 more members that could otherwise be auto-copied just fine
// with the automatically generated copy constructor
{}
...
private:
std::unique_ptr<Base> b;
//10 more data members
};
Now, I found a way to auto-clone Foo::b, by writing a wrapper over unique_ptr that defines the copy constructor and assignment by calling clone.
template <typename T>
class auto_cloned_unique_ptr
{
private:
std::unique_ptr<T> up;
public:
// copy constructor
auto_cloned_unique_ptr(auto_cloned_unique_ptr<T> const& other)
: up(other.up->clone()) {}
// copy assignment
auto_cloned_unique_ptr<T>& operator =(auto_cloned_unique_ptr<T> const& other)
{
this->up = other.up->clone();
return *this;
}
auto_cloned_unique_ptr(std::unique_ptr<T> _up)
: up(std::move(_up)) {}
// Delegate everything else to unique_ptr
auto_cloned_unique_ptr(auto_cloned_unique_ptr<T>&& other)
: up(std::move(other.up)) {}
auto_cloned_unique_ptr<T>& operator =(auto_cloned_unique_ptr<T>&& other)
{
this->up = std::move(other.up);
return *this;
}
auto operator *() const {return *up;}
auto operator->() const {return up.operator->();}
auto get() -> const {return up.get();}
};
Now if we use this we don't need to define our own copy constructor:
class Foo2 {
public:
...
private:
auto_cloned_unique_ptr<Base> b;
//10 more data members
};
Is such an approach very much frowned upon (for using a non-standard wrapper over unique_ptr)?

Let me first paraphrase what you want to do: You want that each instance of Foo has its own instance of Base in b; in particular, if you copy a Foo, the copy will have its own new Base, initially with the same "value". In other words, Base should behave like a value.
At the same time, you can't store Base directly in Foo because it is an abstract class. In other words, you want b to be polymorphic.
There you have it: you want a polymorphic value. Other people have recognized this need and proposed for C++20 as polymorphic_value<Base>. From the documentation:
The class template, polymorphic_value, confers value-like semantics on
a free-store allocated object. A polymorphic_value may hold an
object of a class publicly derived from T, and copying the
polymorphic_value will copy the object of the derived type.
It has a reference implementation that you can use as of now. Very simply put, it is an wrapper around std::unique_ptr similar to what you propose.

The problem with your approach is that it is changing the meaning of a unique_ptr. The key thing about a unique_ptr is that it tells who is the owner of an object. If you add a copy constructor for unique_ptr, what does that mean? Are you copying the ownership? A and B both uniquely own the thing? That does not make sense. If they share ownership, then you should be using the shared_ptr to indicate the shared ownership. If you want to have a unique owner of a copy of the object, you would naturally indicate that by make_unique(*pFoo). With base and derived objects, having the base object have a
virtual unique_ptr<Foo> Clone() const=0;
is a perfectly normal construct. That is, the derived classes know how to copy themselves so they don't produce a sliced copy, but they return a unique_ptr to the base class to indicate that you will own the copy they have produced. Within these clone operations, yes, you will need to explicitly handle non-copyable members of the derived classes, so you won't be able to just use a default or generated copy constructor. You need to answer "what does it mean to copy something that contains this thing that can't be copied?"
As a concrete example, what would it mean to copy a derived class that had a mutex? What if it were locked and another thread were waiting on it? See why it's hard to give a general answer?

This approach is fine, but you should be very carefull not to clone your objects when you did not intentd to.
Also inherriting from unique_ptr might improve performance

Related

Using "rule of zero" when I have pointers for polymorphism

For the "rule of zero", I understand that I want to separate data management out into simple classes implementing rule of 3, rule of 5, whatever, so that the the more complicated classes can use constructors, assignment operators, etc, as automatically provided.
How does this work when a class member has to be a pointer because of polymorphism?
E.g., suppose I have a class
class MyClass{
private:
s_array<int> mynumbers;
s_array<double> mydoubles;
Base * object;
...
};
Here, Base is a base class with multiple derived classes, and object may be point to one of the derived classes. So object is a pointer in order to get polymorphism.
If it wasn't for the presence of this Base pointer, I could use the rule-of-zero for MyClass assuming s_array<> is properly implemented. Is there a way to set things up so that MyClass can use the rule of zero, even though object is a pointer? The behavior that I want on copy is that a new instance of MyClass gets a pointer to a new copy of object.
If you want to apply the rule of 0 with pointers, you need to use a shared pointer:
shared_ptr<Base> object;
However this doesn't fully fulfil your requirement. Because shared_ptr will provide for the rule of 5, but the copied pointers will always point to the same original object.
To get the behavior that you want, you'd need to create your own smart pointer that provides for the rule of 3 or 5.
If multiple MyClass objects can point to the same Base object, then simply use std::shared_ptr<Base> instead of Base* for your object member, as other responders mentioned.
But, if each MyClass object needs to point to its own Base object, then you have no choice but to implement the Rule of 3/5 in MyClass so that it can create its own Base object and/or clone a Base object from another MyClass object.
Just for the record, what I using to solve this is the following (basically as suggested as above):
template <class myClass>
class clone_ptr
{
public:
clone_ptr(){location=nullptr;}
clone_ptr(myClass* d) { location = d;}
~clone_ptr() { delete location; }
clone_ptr(const clone_ptr<myClass>& source){
if (source.location!=nullptr){
location=source.location->Clone();
}
else
location=nullptr;
}
clone_ptr& operator= (const clone_ptr<myClass>& source){
if (&source!=this){
if (source.location!=nullptr){
location=source.location->Clone();
}
else
location=nullptr;
}
return *this;
}
myClass* operator->() { return location; }
myClass& operator*() { return *location; }
private:
myClass* location;
};
I am implementing the Clone() function in the appropriate classes as follows:
class myClass : public parentClass{
...
public:
myClass* Clone()
{
return new myClass(*this);
}

copy constructor on base class

List C.67 in the cpp core guideline says: A base class should suppress copying, and provide a virtual clone instead if "copying" is desired.
If the copy constructor is defined as deleted in the base, then the move operations are also suppressed for base class and all derived classes.
On the other hand, move operations may improve performance. My question is what would be realistic approach we should adopt when we design a class hierarchy?
Suppose we have the following class hierarchy? how should we design A and B to properly support copy and move operations.
class A{
public:
A(const std::string& as) = deleted;
//should we define other copy/move operators?
virtual void foo();//
virtual ~A();//
private:
std::string s;
};
class B: public A{
public:
//how do we define copy/move operators?
void foo() override;
~B() override;
private:
std::vector<std::string> vs;
};
Confusions
Copy vs. clone
First, note that clone is not “copy for objects of polymorphic type”: they are simply different operations with different semantics.
Copy (via a copy constructor) means “create an object of statically specified type with the value of another”. (Recall that constructors cannot be virtual, for want of a current object whose class could provide the behavior.) The user must specify the type, and should expect that the copied object is “reinterpreted” (sliced) as the known, specified type if it is in fact of a derived type.
clone copies an object of a dynamically known derived class as another object of that class. Since the argument determines the type of the result, the user cannot specify it and indeed does not (statically) know what is chosen. (Heap allocation is a corollary.)
Which one you want depends on what lifetime and type you want the result to have (including “the same type as that one” as a choice). I find it puzzling that someone would write a copy (e.g., a by-value parameter whose specified type is a concrete base class) and be surprised by what they had chosen.
Virtual assignment
Next, note that an abstract class need not fear slicing except on assignment (which must be via a reference). Assignment can be virtual (since an object already exists), but it can’t statically avoid slicing because the types need not match:
struct B {
virtual ~B()=default;
virtual B& operator=(const B&)=default;
// ...
};
struct D1 : B {
D& operator=(const B&) override;
// ...
};
struct D2 : B {/* ... */};
void f() {
B &&b=D1();
b=D2(); // ok
}
The assignment must use just the common B part, or… throw? If the assignment can fail, it’d be clearer to provide it as a function: perhaps bool assign_like(const B&) &; that returns false if the types differ.
Protection
So we indeed must do something about at least assignment if we want to avoid the risk of slicing. The Core Guidelines idea of deleting the assignment operator is reasonable, but I would just make it protected in each abstract base class.
Concrete leaves only
If you never inherit from a concrete class, that’s all you need to prevent slicing: the implicit (public) special member functions in the leaf classes do not slice, automatically use the base’s corresponding SMFs, and can in turn be used automatically as appropriate. (For example, the concrete classes may then be passed by value.)
“Deep” hierarchy
In a concrete base class, you have two choices for each SMF:
Make it protected anyway, denying the possibility of deliberately copying an object (even if the source’s complete object type is known statically).
Leave it available and send any confused users of the class hierarchy here to learn about the difference between copy and clone (and the impossibility of a “fully virtual” assignment).

How to approach copying objects with smart pointers as class attributes?

From the boost library documentation I read this:
Conceptually, smart pointers are seen as owning the object pointed to,
and thus responsible for deletion of the object when it is no longer
needed.
I have a very simple problem: I want to use RAII for pointer attributes of a class that is Copyable and Assignable.
The copy and assignment operations should be deep: every object should have its own copy of the actual data. Also, RTTI needs to be available for the attributes (their type may also be determined at runtime).
Should I be searching for an implementation of a Copyable smart pointer (the data are small, so I don't need Copy on Write pointers), or do I delegate the copy operation to the copy constructors of my objects as shown in this answer?
Which smart pointer do I choose for simple RAII of a class that is copyable and assignable? (I'm thinking that the unique_ptr with delegated copy/assignment operations to the class copy constructor and assignment operator would make a proper choice, but I am not sure)
Here's a pseudocode for the problem using raw pointers, it's just a problem description, not a running C++ code:
// Operation interface
class ModelOperation
{
public:
virtual void operate = ();
};
// Implementation of an operation called Special
class SpecialModelOperation
:
public ModelOperation
{
private:
// Private attributes are present here in a real implementation.
public:
// Implement operation
void operate () {};
};
// All operations conform to ModelOperation interface
// These are possible operation names:
// class MoreSpecialOperation;
// class DifferentOperation;
// Concrete model with different operations
class MyModel
{
private:
ModelOperation* firstOperation_;
ModelOperation* secondOperation_;
public:
MyModel()
:
firstOperation_(0),
secondOperation_(0)
{
// Forgetting about run-time type definition from input files here.
firstOperation_ = new MoreSpecialOperation();
secondOperation_ = new DifferentOperation();
}
void operate()
{
firstOperation_->operate();
secondOperation_->operate();
}
~MyModel()
{
delete firstOperation_;
firstOperation_ = 0;
delete secondOperation_;
secondOperation_ = 0;
}
};
int main()
{
MyModel modelOne;
// Some internal scope
{
// I want modelTwo to have its own set of copied, not referenced
// operations, and at the same time I need RAII to for the operations,
// deleting them automatically as soon as it goes out of scope.
// This saves me from writing destructors for different concrete models.
MyModel modelTwo (modelOne);
}
return 0;
}
If you accept some requirements on your types, this can be done without requiring implementing virtual clone functions for all types. The particular requirements are that the types have accessible copy constructors, which some would deem undesirable because of potential for accidental slicing. Proper use of friending may mitigate the drawbacks of that, though.
If such is acceptable one can go about this by erasing the derived types under an interface that provides copy functionality:
template <typename Base>
struct clonable {
// virtual copy
// this clone function will be generated via templates
// no boilerplate is involved
virtual std::unique_ptr<clonable<Base>> clone() const = 0;
// expose the actual data
virtual Base* get() = 0;
virtual Base const* get() const = 0;
// virtual destructor
// note that this also obviates the need for a virtual destructor on Base
// I would probably still make it virtual, though, just in case
virtual ~clonable() = default;
};
This interface is implemented by a class templated on the most derived type, and thus knows how to make normal copies through the copy constructor.
template <typename Base, typename Derived>
struct clonable_holder : clonable<Base> {
// I suppose other constructors could be provided
// like a forwarding one for emplacing, but I am going for minimal here
clonable_holder(Derived value)
: storage(std::move(value)) {}
// here we know the most derived type, so we can use the copy constructor
// without risk of slicing
std::unique_ptr<clonable<Base>> clone() const override {
return std::unique_ptr<clonable<Base>>(new clonable_holder(storage));
}
Base* get() override { return &storage; }
Base const* get() const override { return &storage; }
private:
Derived storage;
};
This will generate virtual copy functions for us without extra boilerplate. Now we can build a smart pointer-like class on top of this (not quite a smart pointer because it does not give pointer semantics, but value semantics instead).
template <typename Base>
struct polymorphic_value {
// this constructor captures the most derived type and erases it
// this is a point where slicing may still occur
// so making it explicit may be desirable
// we could force constructions through a forwarding factory class for extra safety
template <typename Derived>
polymorphic_value(Derived value)
: handle(new clonable_holder<Base, Derived>(std::move(value))) {
static_assert(std::is_base_of<Base, Derived>::value,
"value must be derived from Base");
}
// moving is free thanks to unique_ptr
polymorphic_value(polymorphic_value&&) = default;
polymorphic_value& operator=(polymorphic_value&&) = default;
// copying uses our virtual interface
polymorphic_value(polymorphic_value const& that)
: handle(that.handle->clone()) {}
polymorphic_value& operator=(polymorphic_value const& that) {
handle = that.handle->clone();
return *this;
}
// other useful constructors involve upcasting and so on
// and then useful stuff for actually using the value
Base* operator->() { return handle.get(); }
Base const* operator->() const { return handle.get(); }
// ...
private:
std::unique_ptr<clonable<Base>> handle;
};
This is just a minimal interface, but it can easily be fleshed out from here to cover more usage scenarios.
It's a bit late, but for future viewers: There's a ready-to-use implementation in my header-only library Aurora and its SmartPtr tutorial. With Aurora, it's trivial to implement deep-copy through smart pointers. The following code works for any copyable type T:
aurora::CopiedPtr<T> first(new T);
aurora::CopiedPtr<T> second = first; // deep copy
This makes it often unnecessary to implement The Big Three/Five if your classes have pointer members.
It sounds like need to be able to make a smart pointer that creates a new copy of the object each time another smart pointer object is created. (Whether that copy is "deep" or not is up to the constructor of the object, I guess; the objects you're storing could have many levels deep of ownership, for all we know, so "deep" depends on the meaning of the objects. The main thing for our purposes is that you want something that creates a distinct object when the smart pointer is constructed with a reference from another one, rather than just taking out a pointer to the existing object.)
If I've understood the question correctly, then you will require a virtual clone method. There's no other way to call the derived class's constructor correctly.
struct Clonable {
virtual ~Clonable() {}
virtual Clonable* clone() = 0;
};
struct AutoPtrClonable {
AutoPtrClonable(Clonable* cl=0) : obj(cl) { }
AutoPtrClonable(const AutoPtrClonable& apc) : obj(apc.obj->clone()) { }
~AutoPtrClonable() { delete obj; }
// operator->, operator*, etc
Clonable* obj;
};
To use sample code, make it into a template, etc.
I've never heard about ready-to-use realisation, but you can simply do it by yourself.
First of all your should write some template wrapper class which has virtual clone method, returning copy of stored object. And then write some polymophic holder of that class which would be copyable
and don't forget about checked delete
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Checked_delete
You have two solutions ( actually you have many more, but these make most sense to me :) ):
First, you can use std::unique_ptr. This is a good solution because it forces you to have one instance per pointer. (using std::shared_ptr instead would work as well, but if you do not add the code explicitely, copy and assignment for shared_ptr will "share" - especially what you want to avoid).
If you use std::unique_ptr, your copy constructor and assignment operator should explicitly deep-copy (using either a virtual clone method in the pointee's interface, or new operator in the call to the unique_ptr constructor).
Second, you can roll your own. There's nothing complicated about it, and we're talking about a small (10-20 lines or so) utility class.
Personally, if I had to use this smart pointer class in one place, I would use std::unique_ptr. Otherwise (multiple pointers, same behavior) I would roll my own, simply so I wouldn't have to repeat the deep copy for many instances (to keep with the DRY principle).

C++ Prevent copy a member data

I have a unusual situation,
Say I have a class like the following,
template <typename T>
class C
{
public :
C (int size) : value_(size), some_other_member_(size) {}
T &value () {return value_;}
const T &value() const {return value_;}
private :
T value_;
SomeOtherType some_other_member_;
};
The class designed such that the client can have full access to the member value_, just like std::vector's operator[] will return a reference, this class also have to give client the full access through returning a reference. A setter/getter pair will not do.
However, unlike std::vector, I don't want to allow the client to be able to replace the member entirely. That is, the client shall be able to call const or non-const members of value_, but the following shall not be allowed,
C<SomeType> c(10);
SomeType another_value(5);
c.value() = another_value; // This shall not be allowed
Is there any possible way that I can give client the full access to value_. In some sense, the class C shall be like a container, but once the thing it contained is initialized (through the constructor, there are requirements to T, but that is not relevant here), client can only modify value_ through T's member functions, not replace value_ by assignment.
However, requires T be un-copyable is not an option to me. Because the class C can be copied. At the core of the problem, is that as seen in the class C, C has a few members, they all have a size property, when constructed, they are all constructed with the same size, if value_ is allowed to be replaced through assignment, then it allows the data structure being corrupt in the sense that members may no longer have the same size property.
Requiring T to only allow copy or assignment when the size is the same is also not an option. Because, when copy a C object, the size can be different between the source and the destination. For example,
C c1(10);
C c2(20);
c1 = c2;
is perfectly reasonable. The size of c1 is changed, but all of its members are also changed to the same new size, so it is OK.
I hope I have stated the problem clear. I summary, I want C does not pose much restriction on T, T can be basically any type with a required constructor. T can be copied and assigned. The only thin I don't want client to do is assignment to value_ through C::value().
If you want the user to be able to call non-const member functions on the object and you want to return a reference to the actualy object, you can't completely prohibit assignment, since the assignment operator is basically just that (you can rewrite a = b as a.operator=(b)). Therefore you either need to return only a const reference to your object, make the contained object non_copyable or live with the fact, that it can be assigned to.
Personally I would suggesting rethinking the design. Even if you could disallow assignment, there are really no guarantees that the object doesn't have a member function, which does basically the same think (.swap(...) is a typical candidate), so you haven't really won anything as long as you allow calling non const memberfunctions.
However if you are only concerned with disallowing accidential assignments, you can make it harder to make such an assignment. If your T isn't a builtin, you could create a derived class, which doesn't expose a public assignment operator and return a reference to that:
template <typename T>
class C{
public :
class Derived: public T {
private:
Derived(int size):T(size) {}
Derived& operator=(const Derived&) = default; //used C++11 syntax for brevity, for C++03 code it has to be implemented here
Derived(const Derived&) = default; //don't want this class to be copyied outside of C
~Derived() = default;
friend class C;
};
C (int size) : value_(size), some_other_member_(size) {}
Derived& value () {return value_;}
const Derived& value() const {return value_;}
private :
Derived value_;
SomeOtherType some_other_member_;
};
This will give access to all public members by inheritence, but hide assignment operator (and constructors). Of course if you use c++11, this code could be enhanced by using/defining move constructors/assignments and using perfect forwarding, to allow different constructors. Note that the T-part of Derived can still be assigned to using static_cast<T&>(C.value()) = foo;
To support types you can't derive from (builtins...), you'd need to create a proxy, which exposes all functionality except assignments.
As to your getter/setter problem, I would write
const T& value() const; // as getter
void value(const T&); // as setter
Returning const T& (const-reference) is exactly against situations like c.value() = 10 (see eg. Effective C++ by Scott Meyers, item 23).
I think this also solves the copy problem: your class remains copyable.

What's the use of the private copy constructor in c++

Why do people define a private copy constructor?
When is making the copy constructor and the assignment operator private a good design?
If there are no members in the class which are pointers or handles to a unique object (like file name), then wat other cases are there where private copy constructor is a good idea?
Same question apply for assignment operator. Given that majority of C++ revolves around copying of objects and passing by reference, are there any good designs which involve private copy constructor?
One use case is the singleton pattern where there can only be exactly one instance of a class. In this case, you need make your constructors and assignment operator= private so that there is no way of creating more than one object. The only way to create an object is via your GetInstance() function as shown below.
// An example of singleton pattern
class CMySingleton
{
public:
static CMySingleton& GetInstance()
{
static CMySingleton singleton;
return singleton;
}
// Other non-static member functions
private:
CMySingleton() {} // Private constructor
~CMySingleton() {}
CMySingleton(const CMySingleton&); // Prevent copy-construction
CMySingleton& operator=(const CMySingleton&); // Prevent assignment
};
int main(int argc, char* argv[])
{
// create a single instance of the class
CMySingleton &object = CMySingleton::GetInstance();
// compile fail due to private constructor
CMySingleton object1;
// compile fail due to private copy constructor
CMySingleton object2(object);
// compile fail due to private assignment operator
object1 = object;
// ..
return 0;
}
Some objects represent particular entities that can't or shouldn't be copied. For example, you may prevent copying of an object that represents the log file used by an application, corresponding to the expectation that a single log file will be used by all parts of the code. Use of an accidentally or inappropriately copied object could lead to out-of-order content appearing in the log, inaccurate records of current log size, multiple attempts (some failing) to "roll" to a new log filename or rename the existing one.
Another use is to enforce copying via a virtual function. As constructors can't be virtual, a common practice is to prevent direct access to the copy constructor and provide a virtual Base* clone() method that returns a copy of the actual run-time type to which a pointer points. This prevents the accidental slicing that Base b(derived) would exhibit.
Another example: a dead-simple smart pointer object that simply deletes the pointer it's given in the constructor: if it doesn't support reference counting or some other manner of handling multiple owners, and doesn't want to have risk awkward unintended std::auto_ptr style transfer of ownership, then simply hiding the copy constructor gives a great little smart pointer that's fast and efficient for the limited cases where it's usable. A compile time error about attempting to copy it would effectively ask the programmer "hey - if you really want to do that change me to a shared pointer, otherwise back off!".
A very bad example:
class Vehicle : { int wheels; Vehicle(int w) : wheels(w) {} }
class Car : public Vehicle { Engine * engine; public Car(Engine * e) : Vehicle(4), engine(e) }
...
Car c(new Engine());
Car c2(c); // Now both cars share the same engine!
Vehicle v;
v = c; // This doesn't even make any sense; all you have is a Vehicle with 4 wheels but no engine.
What does it mean to "copy" a car? (Is a car a car model, or an instance of a car? Does copying it preserve the vehicle registration?)
What does it mean to assign a vehicle to another one?
If the operations are meaningless (or merely unimplemented), the standard thing to do is to make the copy constructor and assignment operator private, causing a compile error if they're used instead of weird behaviour.
A common reason to make copy constructor and copy assignment private is to disable default implementation of these operations.
However, in C++ 0x there are special syntax =delete for such purpose.
So in C++ 0x making copy ctor private seems to be resrtricted to very exotic cases.
Copy ctors and assignments are rather syntactic sugar; so such a "private sugar" seems as symptom of greed :)
Even if the contents of the object aren't pointers or other references, preventing people from copying the object can still be useful. Perhaps the class contains a lot of data, and copying is too heavyweight of an operation.
The "virtual constructor idiom" is an important case where a private or protected copy constructor is needed. A problem arises in C++ where you are given the pointer to a base class, of an object that is actually inherited from this base class, and you want to make a copy of it. Calling the copy constructor would not call the copy constructor of the inheriting class, but actually call the copy constructor of the base class.
Observe:
class Base {
public:
Base( const Base & ref ){ std::cout << "Base copy constructor" ; }
};
class Derived : public Base {
public:
Derived( const Derived & ref ) : Base(ref) { std::cout << "Derived copy constructor"; }
}
Base * obj = new Derived;
Base * obj2 = new Derived(*obj);
The code above would produce the output:
"Base copy constructor"
This is clearly not the behaviour the programmer wanted! The programmer was attempting to copy an object of type "Derived" but instead got back an object of type "Base"!!
The issue is rectified by using the aforementioned idiom. Observe the example written above, re-written to use this idiom:
class Base {
public:
virtual Base * clone () const = 0; //this will need to be implemented by derived class
protected:
Base( const Base & ref ){ std::cout << "Base copy constructor" ; }
};
class Derived : public Base {
public:
virtual Base * clone () const {
//call private copy constructor of class "Derived"
return static_cast<Base *>( new Derived(*this) );
}
//private copy constructor:
private:
Derived( const Derived & ref ) : Base(ref) { std::cout << "Derived copy constructor"; }
}
Base * obj = new Derived;
Base * obj2 = obj->clone();
The code above would produce the output:
"Base copy constructor"
"Derived copy constructor"
In other words, the object that was constructed in of desired type "Derived", and not of the type "Base"!
As you can see, in the Derived type, the copy constructor was intentionally made private, because it would be bad API design to give programmers to ability to accidentally try to call the copy constructor manually, rather than using the clever interface provided by clone(). Put another way, a directly callable public copy constructor available could cause programmers to make the mistake mentioned in part 1. In this case, best practise would have the copy constructor be hidden from view, and only indirectly accessible by using the method "clone()".
You might want to implement some of the methods of the class using a copy constructor, but not to expose it outside of the class. So then you make it private. Like any other method.