How to create a copy of an object from a link to a clean abstract base class?

I want to write a function that works for any derived classes in a specific hierarchy, without changing the input parameter of an abstract class:

class A { public: A(int val): m_i(val) { } virtual void add(int i) = 0; int m_i; }; class B: public A { public: B(int val): A(val) { } B(): A(0) { } virtual void add(int i) { m_i += i; } }; class C: public A { public: C(int val): A(val) { } C(): A(0) { } virtual void add(int i) { m_i += i*2; } }; int f(const A& base_class) { // how to create a concrete copy of class base_class? base_class.add(5); } 

Here e () should work like B and C, but I cannot create a copy of a specific class because I do not know the actual type if I use dynamic_cast.

Is there any other approach to solve this problem or should just use dynamic_cast?

+4
source share
3 answers

A typical approach, commonly known as the idiom of a virtual constructor , is to define another virtual method for cloning a particular class, make it virtual in an abstract base, and call it as needed to instantiate the desired class without knowing its type:

 class A { public: A(int val): m_i(val) { } virtual void add(int i) = 0; virtual A* clone() const = 0; // Override in derived classes to return new B/C int m_i; }; 
+2
source

The problem is that you pass const A& , but add not const , if you remove the const modifier, then this works:

 int f(A& base_class) { // how to create a concrete copy of class base_class? base_class.add(5); ///Need a return here } 

I am using gcc , and an error that really tells you what is happening:

 error: no matching function for call to 'A::add(int&) const' base_class.add(a); ^^^^^ no known conversion for implicit 'this' parameter from 'const A*' to 'A*' ^^^^^^^^ 

Based on your answer, another option is make m_i mutable and make const member methods as follows:

 class A { public: A(int val): m_i(val) { } virtual void add(int i) const = 0; protected: mutable int m_i; }; class B: public A { public: B(int val): A(val) { } B(): A(0) { } virtual void add(int i) const { m_i += i; } }; class C: public A { public: C(int val): A(val) { } C(): A(0) { } virtual void add(int i) const { m_i += i*2; } }; int f(const A& base_class) { base_class.add(5) ; //Need a return here } 
+1
source

From your question it is not clear why you even need to make a copy.

However, if you do, you can use the clone() method:

 class A { public: virtual A* clone() const = 0; }; class B: public A { public: virtual B* clone() const { return new(*this); } }; class C: public A { public: virtual C* clone() const { return new(*this); } }; 
0
source

All Articles