Currently I am working on some algebra problem. I have an (almost abstract) base class from which several classes will be derived. All these classes will contain lists of numbers that are ordered in a lot of very different ways.
On the base class I want to define some operators that will be implemented for each of the derived classes. The idea is that once this library is finished, I don't have to care anymore about the intrinsics of the derived class. Once I initialize some derived class, I can refer to it by a reference (or pointer) of base-type and through that access all the derived operations.
I would like to setup rather complex algorithms, based on the operations that were defined on the base class. Therefore I want to be able to access these algorithms only via the base class. In that way it should easily generalize to many types of derived classes.
I have understood that this is exactly what object oriented programming is about, so that is why I ended up using C++.
I have setup most of what I want in a way similar to this example (works with g++):
#include <iostream>
class base;
base & gettype(const base&);
class base{
public:
int x;
int type;
base() = default;
base(int in){
this->type=0;
this->x = in;
}
virtual base & operator+= ( const base & other){
this->x += other.x;
return *this;
}
virtual base & operator+ ( const base & other){
base & ret = gettype(*this);
ret += other.x;
return ret;
}
virtual void print(){
std::cout << "base is: " << x << "\n";
}
};
class der1:public base{
public:
int a;
der1(){}
der1(int in){
this->x = in;
this->a = 2*in;
this->type=1;
}
base & operator+= ( const base & other){
std::cout <<"used der add\n";
const der1 & otherder = static_cast<const der1 &>(other);
this->x += otherder.x;
this->a += otherder.a;
return *this;
}
void print(){
std::cout << "der1 is: " << x << " " << a << "\n";
}
};
base & gettype(const base & in){
if(in.type==0){
return * new base();
}
if(in.type==1){
return * new der1();
}
}
main(){
base baseobj(2);
baseobj.print();
baseobj += baseobj;
baseobj.print();
(baseobj+baseobj).print(); //Answer is right, but there is a memory leak
der1 derobj(3);
derobj.print();
derobj += derobj;
base * test = new der1(4);
test->print();
(*test) += (*test);
test->print();
base & test2 = *test;
test2 += test2;
test2.print(); //All these print the right answers as well
delete test;
}
But there is a memory leak inside this. Whenever I do something like x=x+y, then the memory that is allocated in the gettype function is not freed anymore.
I have read that it is rather uncommon to have an operator+ function return a reference. However, I cannot make this work in a satisfactory manner when operator+ returns by value. The reason is that when it returns by value, it will return an object sliced as base object. When I define derived operator+ functions with covariant types (like in the example below), they are not used, because I only use base type references, not der1.
#include <iostream>
class base{
public:
int x;
base() = default;
base(int in){
this->x = in;
}
virtual base & operator+= ( const base & other){
this->x += other.x;
return *this;
}
virtual base operator+ ( const base & other){
base ret(*this);
ret += other.x;
return ret;
}
virtual void print(){
std::cout << "base is: " << x << "\n";
}
};
class der1:public base{
public:
int a;
der1(int in){
this->x = in;
this->a = 2*in;
}
der1 & operator+= ( const der1 & other){
this->x += other.x;
this->a += other.a;
return *this;
}
der1 operator+ ( const der1 & other){
der1 ret(*this);
ret += other.x;
return ret;
}
void print(){
std::cout << "der1 is: " << x << " " << a << "\n";
}
};
main(){
base baseobj(2);
baseobj.print();
baseobj += baseobj;
baseobj.print();
(baseobj+baseobj).print(); //This all works nicely for the base class
der1 derobj(3);
derobj.print();
base * test = new der1(4);
test->print(); //derived print function
base & test2 = *test;
test2 += test2; //base add function, because argument base&
test2.print(); //Indeed, wrong answer.
}
So is it possible to create a library that I can use in a manner similar to this:
base & x = getderived(3) // This will return a (reference/pointer to) derived type
base & y = getderived(3)
x +=y;
x = x+3*y;
//And a whole lot of other operations
delete x
delete y // I don't mine some manual memory management
I hope it is clear what I want to achieve. If you think it is impossible, I'm also happy to with that answer, then I know I have to stop looking further. (If there's no solution, I'll keep my current approach and have to work with += like operators, and skip the binary ones. This is not entirely bad)
In C++ you should never use explicit new/delete and you should follow RAII.
If I understood your issue, I would get rid of type and gettype and instead use a virtual clone:
class base
{
public:
virtual std::unique_ptr<base> clone() const
{
return std::make_unique<base>(*this);
}
};
class derived : public base
{
public:
std::unique_ptr<base> clone() const override
{
return std::make_unique<derived>(*this);
}
};
Related
I was wondering how should I (or can I? does it make any sense?) overload the assignment operator when working with inheritance and upcasting?
Let's say we have Base class and Derived class (inherited from Base). If i have something like:
/// supose we have one overloaded assignment operator in Base like Base& operator=(const Base&) and
///one in Derived like Derived& operator=(const Derived&)...
Base* a, *b;
Derived c,d;
a = &c;
b = &d;
*a = *b /// this will call the function in Base
If that calls the Base function, why should I overload "=" again in Derived? Is overloading assignment operator in Derived necessary only for working directly with objects, not upcasting (pointers) ?
Here's some code that hopefully helps you out.
Derived Does Not Own A Dynamic Resource
The Base class holds a dynamic resource, so we are required to follow the Rule of 3 (should be 5, but kept it at 3 for brevity). I did so by utilizing the copy/swap idiom.
I then derive Derived from Base. It does not hold a dynamic resource, so I follow the Rule of 0 and don't provide a custom copy constructor, destructor, assignment operator, move constructor, or move assignment.
You can see from the output that the Base portion of the Derived objects are able to deep-copy themsleves just fine, and the Derived-only portion gets by just fine with shallow copy. The final output leaks memory, but I chose to do that to demonstrate an actual overwrite using a pointer to Base.
#include <iostream>
class Base {
private:
int* m = nullptr;
public:
Base() = default;
Base(int v) : m(new int(v)) {}
Base(const Base& other) : m(new int(*(other.m))) {}
virtual ~Base() {
delete m;
m = nullptr;
}
Base& operator=(Base other) {
swap(*this, other);
return *this;
}
friend void swap(Base& lhs, Base& rhs) {
using std::swap;
swap(lhs.m, rhs.m);
}
virtual void print() const {
std::cout << "Address: " << m << "\nValue: " << *m << '\n';
}
};
class Derived : public Base {
private:
double x = 0.0;
public:
Derived() = default;
Derived(double v) : Base(), x(v) {}
Derived(int i, double v) : Base(i), x(v) {}
void print() const override {
std::cout << "Address: " << &x << "\nValue: " << x << '\n';
Base::print();
}
};
int main() {
std::cout << "A\n";
Base* a = new Derived(5, 3.14);
a->print();
std::cout << "\nB\n";
Derived b = *(dynamic_cast<Derived*>(a)); // Copy ctor
b.print();
std::cout << "\nC\n";
Derived c;
c = b;
c.print();
std::cout << "\nReplace A (This leaks)\n";
a = new Derived(7, 9.81);
a->print();
}
Output:
A
Address: 0x21712d0
Value: 3.14
Address: 0x21712e0
Value: 5
B
Address: 0x7ffdd62964c8
Value: 3.14
Address: 0x2171300
Value: 5
C
Address: 0x7ffdd62964b0
Value: 3.14
Address: 0x2171320
Value: 5
Replace A (This leaks)
Address: 0x2171350
Value: 9.81
Address: 0x2171360
Value: 7
Derived Owns A Dynamic Resource
Now, Derived has a dynamic of its own to manage. So I follow the Rule of 3 and provide a copy constructor, destructor, and assignment operator overload. You'll notice that the assignment operator looks identical to the Base version; this is intentional.
It's because I'm using the copy/swap idiom. So in the swap() function for Derived, I add a step where it swaps the Base portion, then swaps the Derived portion. I do this by invoking the Base swap() function through the dynamic cast.
And we can again observe that all objects have their own memory for each dynamically allocated piece.
#include <iostream>
class Base {
private:
int* m = nullptr;
public:
Base() = default;
Base(int v) : m(new int(v)) {}
Base(const Base& other) : m(new int(*(other.m))) {}
virtual ~Base() {
delete m;
m = nullptr;
}
Base& operator=(Base other) {
swap(*this, other);
return *this;
}
friend void swap(Base& lhs, Base& rhs) {
using std::swap;
swap(lhs.m, rhs.m);
}
virtual void print() const {
std::cout << "Address: " << m << "\nValue: " << *m << '\n';
}
};
class Derived : public Base {
private:
double* x = nullptr;
public:
Derived() = default;
Derived(double v) : Base(), x(new double(v)) {}
Derived(int i, double v) : Base(i), x(new double(v)) {}
Derived(const Derived& other) : Base(other), x(new double(*(other.x))) {}
~Derived() {
delete x;
x = nullptr;
}
Derived& operator=(Derived other) {
swap(*this, other);
return *this;
}
friend void swap(Derived& lhs, Derived& rhs) {
using std::swap;
swap(dynamic_cast<Base&>(lhs), dynamic_cast<Base&>(rhs));
swap(lhs.x, rhs.x);
}
void print() const override {
std::cout << "Address: " << &x << "\nValue: " << *x << '\n';
Base::print();
}
};
int main() {
std::cout << "A\n";
Base* a = new Derived(5, 3.14);
a->print();
std::cout << "\nB\n";
Derived b = *(dynamic_cast<Derived*>(a)); // Copy ctor
b.print();
std::cout << "\nC\n";
Derived c;
c = b;
c.print();
std::cout << "\nReplace A (This leaks)\n";
a = new Derived(7, 9.81);
a->print();
}
Output:
A
Address: 0x14812d0
Value: 3.14
Address: 0x14812e0
Value: 5
B
Address: 0x7fffe89e8d68
Value: 3.14
Address: 0x1481320
Value: 5
C
Address: 0x7fffe89e8d50
Value: 3.14
Address: 0x1481360
Value: 5
Replace A (This leaks)
Address: 0x14813b0
Value: 9.81
Address: 0x14813c0
Value: 7
Does the output of this example help clarify your question? You could always override the operator= in the derived class as follows:
#include <cstdio>
struct Base{
virtual ~Base() = default;
virtual void operator=(const Base&) {
std::printf("Base::=\n");
}
};
struct Derived: public Base {
void operator=(const Derived&) {
std::printf("Derived::=\n");
}
void operator=(const Base&) override{
std::printf("Derived::= Base\n");
}
};
int main() {
Base* a, *b;
Derived c,d;
a = &c;
b = &d;
*a = *b; //Dispatches the call to the derived class =
Base base;
Derived derived;
derived = base; //Usual case now after operator=(const Base&) in Derived
c = d; //Usual case
Base base1, base2;
base1 = base2; //Usual case
a = &base1;
b = &base2;
*a = *b; //Usual case
}
Output:
Derived::= Base
Derived::= Base
Derived::=
Base::=
Base::=
I have the following class structure:
class Base{
public:
Base() {}
Base(const Base& b){
cout << "Base Copy" << endl;
*this = b;
}
Base baseOperation(Base& base){
return Base();
}
};
class Derived : public Base{
public:
Derived(){}
Derived( const Base &d ) : Base(d)
{
cout << "Derived Copy: " << endl;
}
Derived operation(Derived& input){
return baseOperation(input);
}
};
Base is basically a library I am using. It has an operator called baseOperation, that takes in itself and returns an output; I want to wrap around that output but without making both a copy of base and of derived. It is making double copies now which slows my program down. Is there a way to avoid this
The only copy here could be while constructing Derived object in the return statement of
Derived operation(Derived& input){
return baseOperation(input);
}
All other copy operations are eliminated by RVO. Of course you can change copying to moving if you have access to sources of Base. But maybe it is worth to consider aggregation instead of inheritance.
I have the following code:
#include <iostream>
using namespace std;
class Base {
public:
Base operator/(const Base& other){
Base res;
cout << "Base /" << endl;
return res;
}
Base& operator/=(const Base& other){
cout << "Base /=" << endl;
return *this;
}
};
class Derived : public Base {
public:
Derived operator/(const Derived& other){
Derived res;
cout << "Derived /" << endl;
return res;
}
};
int main() {
Derived d1, d2;
Base b1, b2;
b1 = d1 / d2;
b2 = d1 /= d2;
}
The second assignment outputs Base /=. Can I achieve that the second assignment to use the overridden operator/, without overriding operator/=? I think I have to implement one operator using the other.
This is a homework, so it is OK to give just the basic idea what to do.
Though being clearly not the preferred way and probably some sort of "ugly", it is possible to use Derived::operator/ without providing a Derived::operator/=. To do that, the following steps are necessary:
call operator / in the implementation of Base::operator/=
Make operator / virtual such that it is not statically bound in /=-implementation
Provide an operator/-implementation in class Derived that overrides the one in the Base, i.e. provide an operator virtual Base operator/(const Base&) in addition to Derived operator/(const Derived&) (note that the latter cannot override since it has a covariant argument type)
In this Derived::operator/(const Base& other)-implementation, check the dynamic type of other and explicitly call the respective implementation.
See the following code:
class Base {
public:
virtual Base operator/(const Base& other) const {
Base res;
cout << "Base /" << endl;
return res;
}
Base& operator/=(const Base& other){
cout << "Base /=" << endl;
*this = *this / other;
return *this;
}
};
class Derived : public Base {
public:
virtual Base operator/(const Base& other) const override {
cout << "Derived /(Base&)" << endl;
if(dynamic_cast<const Derived*>(&other)==0) {
// do something specific here, or call base operator:
return Base::operator/(other);
}
else {
return operator/(dynamic_cast<const Derived&>(other));
}
}
Derived operator/(const Derived& other) const { // cannot override
cout << "Derived /(Derived&)" << endl;
return *this;
}
};
int main() {
Derived d1, d2;
Base b1, b2;
b1 = d1 / d2;
// Output: Derived /(Derived&)
b2 = d1 /= d2;
// Output:
// Base /=
// Derived /(Base&)
// Derived /(Derived&)
return 0;
}
Be aware that an expression Derived d3 = d2 /= d1 is still not possible, because return type Base & of operator Base& Base::operator /= cannot be converted to Derived &.
I'm currently writing a complicated class and in it I basically need to copy a list of derived classes. The simplified version is, as follows:
I have a base class from which I derive several other classes:
class Base
{
public:
virtual void test(void)
{
cout << "Base" << endl;
}
Base(vector<Base*> *pointer)
{
pointer->push_back(this);
}
virtual Base& operator=(const Base& rhs)
{
cout << "Base=" << endl;
return *this;
}
};
class A : public Base
{
public:
void test(void)
{
cout << "A" << endl;
}
A(vector<Base*> *pointer) : Base(pointer) {}
A& operator=(const A& rhs)
{
cout << "A=" << endl;
return *this;
}
};
class B : public Base
{
public:
void test(void)
{
cout << "B" << endl;
}
B(vector<Base*> *pointer) : Base(pointer) {}
B& operator=(const B& rhs)
{
cout << "B=" << endl;
return *this;
}
};
Then I create a list of objects, which I save in the in a pointer list of the Base class:
vector<Base*> listA;
new Base(&listA);
new A(&listA);
new B(&listA);
These objects I then want to copy in a second list with the same classes (same order), but which might have different values.
for (int i = 0; i < (int)listA.size(); i++)
{
(*listA[i]) = (*listB[i]);
}
However c++ is not able to do that. Because the list has the type Base*, dereferencing creates an object of type Base. Therefore the assignment operator= of the Base class is called instead of the correct one from the derived class. How can I fix this?
Or how can I tell c++ to use the right operator? Maybe by some isinstanceof-function?
For a full sample see:
int main()
{
vector<Base*> listA;
new Base(&listA);
new A(&listA);
new B(&listA);
vector<Base*> listB;
new Base(&listB);
new A(&listB);
new B(&listB);
for (int i = 0; i < (int)listA.size(); i++)
{
(*listA[i]).test();
}
for (int i = 0; i < (int)listA.size(); i++)
{
(*listA[i]) = (*listB[i]);
}
}
Which outputs:
Base
A
B
Base=
Base=
Base=
There are a few misunderstandings here. First and foremost, what does it mean to assign an instance of a derived class to an instance of a base class? Let's take a simple hierarchy:
struct A { int x; };
struct B : A { int y; };
A a;
B b;
a = b; // what should this do?
b = a; // what about this?
With normal C++, the first one does object slicing, and the second one is ill-formed. But even the first one, well well-formed, is typically not what you want to do anyway. Are you sure you want to be slicing?
The second is that while you made your assignment operator virtual:
virtual Base& operator=(const Base& rhs)
None of the derived classes actually override it. A's assignment operator takes an A const& and B's takes a B const&. If you marked the two with override, your compiler would point this out to you. If you fix those two to take a Base const& argument, then you would get what you want printed - but it's probably still not what you actually want to have happen.
In order to actually make polymorphic copies, a typical solution is to provide a virtual clone method:
virtual Base* clone() const = 0;
That your derived classes implement:
struct A : Base {
A* clone() const override { return new A(*this); }
};
And then use clone() instead of assignment. There will be no slicing here.
Insert the usual caveats about memory management and raw pointers here.
Okay. I found a solution for my problem. I implemented a copy function which takes the Base class as the argument. Inside this copy function I can copy the variables using the pointa. The classe now are as follows:
class Base
{
public:
virtual void test(void)
{
cout << "Base" << endl;
}
Base(vector<Base*> *pointer)
{
pointer->push_back(this);
}
virtual void clone(Base* pointer) = 0;
};
class A : public Base
{
public:
void test(void)
{
cout << "A" << endl;
}
A(vector<Base*> *pointer) : Base(pointer) {}
void clone(Base* pointer) override
{
A* pointa = (A*)pointer;
cout << "clone A" << endl;
//Clone Variables here
}
};
class B : public Base
{
public:
void test(void)
{
cout << "B" << endl;
}
B(vector<Base*> *pointer) : Base(pointer) {}
void clone(Base* pointer) override
{
B* pointa = (B*)pointer;
cout << "clone B" << endl;
//Clone Variables here
}
};
This means I can now copy the objects in the following way:
for (int i = 0; i < (int)listA.size(); i++)
{
listA[i]->clone(listB[i]);
}
However this solution is not in any way typesafe, a requirement I want to meet. I looked into my idea, and decided to do things manually without the list, which means lot's of duplicated code, but brings peace of mind.
So I'm having a little bit of problems understanding how I should fix this polymorphic issue I've ran into. To make things short, let's define only two levels of classes, a father and two sons:
The parent:
class Entity {
public:
int x;
Entity();
~Entity();
Entity(const Entity&);
Entity &operator=(const Entity&);
};
The two sons:
class EntitySon1 : public Entity {
public:
int b;
EntitySon1();
~EntitySon1();
EntitySon1(const EntitySon1&);
EntitySon1 &operator=(const EntitySon1&);
};
class EntitySon2 : public Entity {
public:
int a;
EntitySon2();
~EntitySon2();
EntitySon2(const EntitySon2&);
EntitySon2 &operator=(const EntitySon2&);
};
Please, forget the fact that in this example all classes only have an int value and the standard operator= should therefore be enough, in the real project these classes are more complex so I do have the need to implement one myself and they are succesfully calling parent ones as well.
So now, somewhere in my project, I have an array of Entity*, which can only be either son1 or son2. I want to go through this array of entities and make copies into another array. The code I'd like to be able to write is something like:
for (i = 0; i < entities; ++i) {
entityCopiesArray[i] = entitiesArray[i];
}
Problem is, both entityCopiesArray and entitiesArray are of type (Entity*) so when the assign is done, only Entity.operator=() gets called, while I need, in the case that current Entity is son1, have both Entity.operator=() and EntitySon1.operator=() called.
I know I can cast each variable on the array so the right operator gets called, but that needs extra information to tell which entities are son1, which are son2, and also need to be typed manually for every possible Entity's son.
Is there any other way around this, or am I stuck with doing:
if (isSon1())
(EntitySon1)entityCopiesArray[i] = (EntitySon1)entitiesArray[i];
else if (isSon2())
(EntitySon2)entityCopiesArray[i] = (EntitySon2)entitiesArray[i];
// ... etc
edit: I made this post late night and tried to compact the information as much as possible so I said things that weren't accurate. I obviously have an array to Entity*, else I wouldn't be able to use polymorphism.
Consider the following:
struct Base {
int a;
};
struct Derived1 : public Base {
int d1Data[100];
};
struct Derived2 : public Base {
char d2Data[1500];
};
Now if we do the following:
Entity* e = new Entity;
Derived1* d1 = new Derived1;
Derived2* d2 = new Derived2;
std::cout << sizeof(*e) << ", " << sizeof(*d1) << ", " << sizeof(*d2) << '\n';
What will the output be? Hint: The numbers are not going to be the same.
So now what happens in each of the following cases?
*e = *(Entity*)d1;
*(Derived1*)e = *d1;
*(Derived2*)d1 = *d2;
*(Entity*)d1 = *(Entity*)(d2);
*(Derived1*)d2 = *d1;
None of these cases is particularly good. Your post makes it sound like you are setting yourself up for a bad case of object slicing.
DO NOT DO.
On the other hand, if what you are looking to do is to clone objects from a list:
std::vector<Base*> entities;
std::vector<Base*> copies;
entities.push_back(new Derived1);
entities.push_Back(new Derived2);
for (size_t i = 0; i < entities.size(); ++i) {
Base* clone = make_a_copy_of(entities[i]);
}
then the way to do this is to add a member function to Base.
struct Base {
int a;
virtual Base* clone() const = 0;
};
struct Derived1 : public Base {
int d1Data[100];
Base* clone() const override {
return new Derived1(*this);
}
};
struct Derived2 : public Base {
char d2Data[1500];
Base* clone() const override {
return new Derived2(*this);
}
};
int main() {
std::vector<Base*> entities;
std::vector<Base*> copies;
entities.push_back(new Derived1);
entities.push_Back(new Derived2);
for (size_t i = 0; i < entities.size(); ++i) {
Base* clone = entities[i]->clone();
}
// remember to delete all the objects we allocated,
// or wrap them with std::unique_ptr
return 0;
}
I will probably be scowled at for using raw pointers like this without using something like std::unique_ptr to ensure the objects have a lifetime, so here is a complete version using unique_ptr. I'm not using make_unique because neither my GCC (4.8.2) or MSVC appear to support it.
#include <iostream>
#include <vector>
#include <memory>
struct Base {
int m_a;
Base(int a) : m_a(a) {}
virtual ~Base() { std::cout << "Dtoring " << m_a << '\n'; }
virtual std::unique_ptr<Base> clone() const = 0;
};
struct Derived1 : public Base {
int d1Data[100];
Derived1(int a) : Base(a) {}
virtual ~Derived1() { std::cout << "D1 at " << (void*)this << " dtord\n"; }
std::unique_ptr<Base> clone() const override { return std::unique_ptr<Derived1>(new Derived1 (*this)); }
};
struct Derived2 : public Base {
char d2Data[10000];
Derived2(int a) : Base(a) {}
virtual ~Derived2() { std::cout << "D1 at " << (void*)this << " dtord\n"; }
std::unique_ptr<Base> clone() const override { return std::unique_ptr<Derived2>(new Derived2 (*this)); }
};
int main()
{
std::vector<std::unique_ptr<Base>> entities;
{
std::vector<std::unique_ptr<Base>> copies;
entities.emplace_back(new Derived1 (3));
entities.emplace_back(new Derived2 (5));
for (auto& ent : entities) {
copies.emplace_back(ent->clone());
}
std::cout << "copies going out of scope\n";
}
std::cout << "entities going out of scope\n";
return 0;
}
Live demo: http://ideone.com/lrgJun
---- EDIT ----
When you inherit a class, you also inherit it's data members into your overall structure. In this example, the effective structure of Derived1 is:
struct Derived1 {
int a; // from Base
int d1Data[100];
};
My implementation of clone is quietly relying on the copy constructor which is essentially doing a memory copy of src to dest, the equivalent of memcpy(this, src, sizeof(*this));. Because of this you don't need to chain calls to clone or anything like that, the magic is done in the copy constructor.
If you need to add instances of Base into your mix, we can implement the clone member in Base - but bear in mind that any "special" members you add to Base are going to be inherited in all the derived classes too.
I'll convolute the classes a little and show you what the copy constructors for Base and Derived1 effectively look like:
struct Base {
int m_int;
double m_double;
std::string m_name;
private:
unsigned int m_baseOnly;
...
};
struct Derived1 : public Base {
// inherited m_int, m_double and m_name
// also inherited m_baseOnly, we just can't access it.
std::array<int, 100> m_data;
std::string m_title;
std::shared_ptr<Base> m_buddy;
...
};
At this point, the actual in-memory structure of a Derived1 looks like this:
Derived1 {
int m_int;
double m_double;
std::string m_name;
unsigned int m_baseOnly;
std::array<int, 100> m_data;
std::string m_title;
std::shared_ptr<Base> m_buddy;
};
Given these definitions, unless we implement our own copy constructor or disable copy construction, this is effectively what the compiler will generate for us:
Base::Base(const Base& rhs) // Base copy constructor
: m_int(rhs.m_int)
, m_double(rhs.m_double)
, m_name(rhs.m_name)
, m_baseOnly(rhs.m_baseOnly)
{
}
Derived1::Derived1(const Derived1& rhs)
: Base(rhs) // copy-construct the Base portion
, m_data(rhs.m_data) // hence why I used std::array
, m_title(rhs.m_title)
, m_buddy(rhs.m_buddy)
{
}
My implementation of clone for Derived1
std::unique_ptr<Base> clone() const override
{
return std::unique_ptr<Derived1>(new Derived1 (*this));
}
or
std::unique_ptr<Base> clone() const override
{
const Derived1& rhs = *this; // Reference to current object.
Derived1* newClone = new Derived1(rhs);
return std::unique_ptr<Derived1>(newClone);
}
which is creating a new Derived1, invoking the new, empty, clone's copy-ctor with the current object as rhs and filling out the clone.
I have an array of Entities, which can only be either son1 or son2.
In general this is not possible. But you can have an array of Entity*, each of which points to a Son1 or a Son2. Then you can have a virtual clone function such that a member of this family creates a copy of itself and returns a pointer (of type Entity*) to it. Then you can copy the array quite easily.