Copying derived entities using only base class pointers, (without exhaustive testing!) - C++
This approach is the preferred way of copying polymorphic objects because it offloads the responsibility of determining how to copy an object of an arbitrary type to that object, rather than trying to determine it at compile-time. More generally, if you don't know what the base class pointer points at at compile-time, you can't possibly know which of the many potential pieces of code you would need to execute in order to get a correct copy. Because of this, any working solution will need a dynamic selection of code, and the virtual function is a good way to do this.
Two comments on your actual code. First, C++ inheritance allows a derived class overriding a base class member function to have the derived function return a pointer of a type more specific than the base class version. This is called covariance. As an example, if a base class function is
virtual Base* clone() const;
Then a derived class can override it as
virtual Derived* clone() const;
And this will work perfectly fine. This allows you, for example, to have code like this:
Derived* d = // something...
Derived* copy = d->clone();
Which, without the covariant overload, wouldn't be legal.
Another detail - in the code you have, you explicitly static_cast
the derived pointers to base pointers in your code. This is perfectly legal, but it's not necessary. C++ will implicitly convert derived class pointers to base class pointers without a cast. If, however, you use the covariant return type idea, this won't come up because the return type will match the type of the objects you'll be creating.
C++: Deep copying a Base class pointer
You need to use the virtual copy pattern: provide a virtual function in the interface that does the copy and then implement it across the hierarchy:
struct base {
virtual ~base() {} // Remember to provide a virtual destructor
virtual base* clone() const = 0;
};
struct derived : base {
virtual derived* clone() const {
return new derived(*this);
}
};
Then the DeepCopy
object just needs to call that function:
class DeepCopy
{
Base * basePtr;
public:
DeepCopy(DeepCopy const & dc) // This should be `const`
: basePtr( dc.basePtr->clone() )
{}
};
Any purpose of using base class pointers to derived class if virtual function is not used
Using a base class pointer or reference allows you to write functions that accept all derived classes of the base generically so you can call common non-virtual functions on them. Otherwise, you'd have to write the same function multiple times for the different derived classes, or use templates.
#include <iostream>
class base_t {
public:
void non_virtual() const { std::cout << "Hello, World!\n"; }
};
class derived_1_t : public base_t { };
class derived_2_t : public base_t { };
void do_something(const base_t& obj) {
obj.non_virtual();
}
int main() {
derived_1_t var1;
derived_2_t var2;
do_something(var1);
do_something(var2);
}
C++ copy of two derived class
If your intent is to just copy the Base class part, make a constructor that receives a base class.
Derived2(const Base& other): Base(other){...};
Derived1(const Base& other): Base(other){...};
Trying to assign derived class object address to vector of base class pointers
Yes, you can do this. Unfortunately, as has already been pointed out in the comments, you made several mistakes trying to implement it:
B var1();
does not call the default constructor but declares a function.To add an element to a vector, use
push_back
(orinsert
,emplace
oremplace_back
). In your case, the subscript operater tries to access an element that is not there.To get the address of a variable, use
&
.*
does the exact opposite, it dereferences a pointer.
What you want is:
vector<A*> objectsvar;
B var1;
objectsvar.push_back(&var1);
Copy constructor for derived class, without testing all the types?
create virtual method Parameter* makeCopy()
in base class and implement it for each of child class and use m_parameters.push_back(p->makeCopy())
Related Topics
Class Template for Numeric Types
No == Operator Found While Comparing Structs in C++
How to Use New Std::Byte Type in Places Where Old-Style Unsigned Char Is Needed
C++ Standard Practice: Virtual Interface Classes VS. Templates
Why Does the Size of a Class Depends on the Order of the Member Declaration? and How
Libzip with Visual Studio 2010
How to Prevent Non-Specialized Template Instantiation
Generating One Class Member Per Variadic Template Argument
How Much Overhead Is There When Creating a Thread
Detect Gcc as Opposed to Msvc/Clang with MACro
Can Nullptr Be Emulated in Gcc
Is There a C++11 Syntax File for Vim
Std::Copy to Std::Cout for Std::Pair