So I am quite confused about copy constructors in C++. I have the following code:
class creature /* abstract class*/
{
private:
string name;
int longevity;
creature_society * cs;
public:
creature(int,int,int,creature_society*);
//creature(const creature&);
virtual ~creature();
virtual int is_a_good() =0;
};
class good_creature : public creature
{
public:
good_creature(int,int,creature_society*);
//good_creature(const good_creature&);
~good_creature();
int is_a_good() //returns 1
};
class bad_creature : public creature
{
public:
bad_creature(int,int,creature_society*);
//bad_creature(const bad_creature&);
~bad_creature();
int is_a_good(void); //returns 0
}
So I have an abstract class called creature , a good_creature and a bad_creature which are a children class of creature .
At my program I also have an array called society which has type of creature* objects. If my creature through a condition is defined as good, I allocate space for it and store it in society array as good_creature. The same happens for bad creature. I construct it as described in the following code:
society = new creature*[M];
for(i=0;i<M;i++)
{
if(condition)
society[i] = new good_creature(L,good,this);
else
society[i] = new bad_creature(L,bad,this);
}
So I have to make a pure virtual function: creature::clone(int position) which if it's either a good_creature or a bad_creature, it has to delete the society[pos] and make a copy of the society[pos-1] through a copy constructor.
So for example my good_creature::clone(int position) is like this:
void good_creature::clone(int position)
{
int cop_pos=position -1; //getting the position before that in order to copy it
delete society[pos];
society[pos] = new good_creature( *society[cop_pos] );
//....
}
I get an error because society[cop_pos] is of type creature*. I tried casting it to good creature but unfortunately I keep getting errors. Is it because I am not calling the copy constructor right, is it because I am not casting right? Any ideas? This has been buffling me for 2 days. Keep in mind I' m a newbie and might have done something wrong.
Also I don't need to define my own copy constructor since all the elements in society[i] point at the same object that is defined by creature_society * cs, so I'm trying to use the default constructors since I do not need deep copy.
Thanks for your time.
UPDATE
A class I forgot to mention and the way I construct society
class creature_society
{
private:
int N; // number of the creatures we want to be made in society
creature ** society;
public:
creature_society(int,int);
~creature_society();
};
You don't know if society[cop_pos] is the correct type, so you cannot safely cast. A better solution is to use a virtual function to create a copy
class creature {
public:
virtual creature* clone() const = 0;
...
};
class good_creature {
public:
good_creature* clone() { return new good_creature(*this); }
...
};
//Similar for bad_creature (and any other derived classes)
In your case you'd call it like this:
society[pos] = society[cur_pos]->clone();
There's no need to know the type of the object you're cloning. The virtual function call takes care of that for you. Note that good_creature::clone returns a good_creature* instead of a creature*. This is a valid overload. A virtual function overload is allowed to return a derived class. In this case you could have it return a creature* as well.
Use polymorphism and virtual dispatch to do the work for you.
Define a clone virtual function in creature class.
class creature
{
virtual creature * clone() = 0;
}
and then override it in children:
class good_creature: public creature
{
virtual creature * clone() override
{
return new good_creature(*this);
}
}
and similar for bad_creature.
Then use it:
society[pos] = society[pos - 1]->clone();
Side note: your design seems to influenced by languages like Java. This is not a (modern) C++-style. For example, in modern C++ ownership is better expressed by unique_ptr instead of pointers. This would make code cleaner and much safer.
The problem is that society is an array of creature, not of good creature, so the copy constructor doesn't apply.
You can define a constructor for good_creature and for bad_creature taking as argument a creature:
good_creature(const creature&);
Related
I am apologize if it is a stupid problem.
I want to do deep copy of a derived class.
I have do a search and found there already exist the topic.
C++: Deep copying a Base class pointer
Copying derived entities using only base class pointers, (without exhaustive testing!) - C++
Some elegant advice has been given, such as using virtual copy pattern.
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);
}
};
In my case, I do not want to use the pointer.
I do not know can we do something similar via reference?
Suppose a base class should define a deepCopy interface, to make sure all derived class can do deep copy.
class Base
{
public:
virtual Base &deepCopy() = 0; // may be not good practice, you can change the deep copy interface
virtual void doSomeThing() = 0;
};
and the derived class may be something like this,but I have no idea how to write that.
class Derived : public Base
{
public:
// should overide interface, and I have no idea how to do that.
Base &deepCopy() override
{
}
void doSomeThing() override
{
// Omitted
}
// do shallow copy
Derived& operator=(const Derived&rhs)
{
// omitted
return (*this);
}
private:
int size;
double *data;
};
If you have good idea, change base interface is ok, as long as not using pointer.
I want using deep copy by follow way:
Derived a;
Derived b = a.deepCopy();
Thanks for your time.
edit
Thanks many advice have been given on the comment. Thanks for your all time.
I am rethink my problem.
I want
(1) polymorphism
(2) enforce derived class implement deepCopy interface.
(3) a = interface for shallow copy and a deepCopy interface for deep copy.
Actually, pointer solution can settle (1),(2),(3) while template solution from walnut can settle (2)(3). They are all good enough.
I am still confused that how to using reference to relize (1)(2)(3) above. May be it is a solution solve the (1)(2)(3) in another pespective.
I am now wonder if it is my fault that I am too adhere to reference ...
i am pretty sure this is a simple question for a long time c++ user, this should be a pattern or the problem should be solved in any other way but given i am Python developer and a total novice with c++ i don't know how it's usually done.
Suppose that i have a class where i want to store a pointer to an object that can be of 1 of two different classes that respects an interface, for example:
class AllPlayers
{
public:
virtual void play();
};
class VlcPlayer: public AllPlayers
{
public:
virtual void play();
};
class Mplayer: public AllPlayers
{
public:
virtual void play();
};
class MyMediaPlayer
{
public:
MyMediaPLayer(int playerType);
AllPlayers m_player;
};
MyMediaPlayer::MyMediaPlayer(int PlayerType)
{
if (PlayerType == 0) {
VlcPlayer tmp_player;
m_player = static_cast<AllPlayers> (tmp_player);
}
else {
Mplayer tmp_player;
m_player = static_cast<AllPlayers> (tmp_player);
}
}
MyMediaPlayer test(0);
test.play();
First, i know this would not work and that it seems pretty normal why but how could i get this effect? i would like to have a member of a class for what i am going to use ever the same methods, implemented using a interface and i would like to avoid trying to cast to every of the derived classes every time i am going to use one of his methods.
C++ is value-based, i.e., if you create an object of a given type you really have an object of this type. This doesn't play nicely with dynamic polymorphism. To get dynamic polymorphism you use a pointer or a reference to the actual object. To also get the life-time straight you typicslly allocate the corresponding object on the stack (make sure your base class has a virtual destructor if you ever release an object of a derived type using a pointer to the base). With this, you should be all set: just call a virtual function of the base class through a pointer to rhe base: When you overridethe function in the derived class this is the function which is called.
If you write
AllPlayers m_player;
that is going to be an instance of AllPlayers and cannot be an instance of a class that derives from it.
You should instead use a pointer and allocate the class on the stack.
For example:
class MyMediaPlayer
{
public:
MyMediaPLayer(int playerType);
~MyMediaPLayer();
AllPlayers m_player;
};
MyMediaPlayer::MyMediaPlayer(int PlayerType)
{
if (PlayerType == 0) {
m_player = new VlcPlayer;
}
else {
m_player = new Mplayer;
}
}
MyMediaPlayer::~MyMediaPlayer()
{
if (0 != m_player) {
delete m_player;
m_player = 0;
}
}
As suggested by #xception use of unique_ptr may relieve you from having to write code to deallocate the instance.
As correctly pointed out by #DietmarKühl you should always declare a virtual destructor in a root class (a base class that does not itself derives from some other class) as is the case with AllPlayers.
class AllPlayers
{
public:
virtual ~AllPlayers();
virtual void play(); // note: this should probably be pure virtual.
};
The reason this will not work is colloquially known as Object Splicing. (Or, for those Harry Potter readers out there, Object Splinching)
Let's look at an example:
class Foo
{
public:
int bob;
float fred;
// Foo(const Foo& otherfoo); // implicit copy constructor
};
class Bar : public Foo
{
public:
double gabe; // gabe newell is fat
char steve; // steve jobs is thin
// Bar(const Bar& otherbar); // implicit copy constructor
};
int main()
{
Foo f;
Bar b;
f.bob = 10;
f.fred = 1.5;
b.bob = 15;
b.fred = 2.5;
b.gabe = 1.77245385091; // sqrt(pi)
b.steve = -4;
f = Foo(b);
return 0;
}
This is legal and valid. Problem is, the implicit copy constructor of Foo is called, and Foo's copy constructor knows nothing about what a Bar is. Only that it contains everything a Foo has, and some extra irrelevant crap. Because of this, only the Foo's data gets preserved; the data unique to the Bar gets spliced off.
It's important to note that this is DEFINED BEHAVIOR: it's doing EXACTLY WHAT YOU TELL IT TO. Casting between a subclass of a base class and a base class is implicit. Furthermore, the behavior of the copy constructor is implicit.
It's also important to note that, under the hood, C++ pointers and references work in the same way. It's perfectly sane to pass the Bar to Foo's copy constructor by reference, this pass by reference does not produce a copy of the object. It's the same as working with a pointer.
The actual splicing takes place as a direct result of the copy constructor biting off more than it can chew. It gets an object with more state than it expected, and its only choice is to ignore the extra state.
With python, this doesn't happen because everything is implicitly stored as a reference type. Since you only work with references (the objects themselves are abstracted away), you never have the opportunity to accidentally splice an object.
So here is the deal, I think I need to go another route regarding the pattern I am using but I thought I would get some expert opinions first.
I have a class (UsingClass) that maintains a dynamic list of Base class pointers. When adding a new object to the list I have to figure out what type of object it is because I can't really make it work in a polymorphic manner. The line below tagged "THIS WILL NOT WORK LIKE I WANT IT TO!!" would ideally polymorphically use the =operator from the Derived class of interest, but unfortunately it only uses the default =operator for the Base class.... probably would work if I made Base pure virtual (basically confine it use to an interface with no data members of its own), but I don't really want to have the Derived classes hold members that are common between both (maybe I need to just cut bait and do it).
I think I may just completely be using the wrong pattern but I don't know what alternatives I should consider.
I know the code does not necessarily compile but please work with me. Thanks in advance!
//code block
class Base {
protected:
int x;
float y;
string type; // default to Derived1 or Dervied2 depending on the object inst
public:
virtual int functionM(int l) = 0;
int functionN(int P);
};
class Derived1 : public Base {
protected:
int a;
public:
int functionM(int l);
float functionR(int h);
};
class Derived2 : public Base {
protected:
int b;
float r;
public:
int functionM(int l);
float functionR(int h);
};
#define MAX_ARRAYSIZE 10
class UsingClass {
private:
Base* myDerived1And2DynamicList[MAX_ARRAYSIZE];
int indexForDynamicList;
public:
void functionAddDerivedToList(*Base myInputPtr) {
if((indexForDyanmicList + 1) < MAX_ARRAYSIZE) {
if(myInputPtr->type == "Derived1") {
myDerived1And2DynamicList[indexForDyanmicList+1] = new Derived1;
*myDerived1And2DynamicList[indexForDyanmicList+1] = *myInputPtr; // THIS WILL NOT WORK LIKE I WANT IT TO!!
} else if (myInputPtr->type == "Derived2") {
myDerived1And2DynamicList[indexForDyanmicList+1] = new Derived2;
*myDerived1And2DynamicList[indexForDyanmicList+1] = *myInputPtr; // THIS WILL NOT WORK LIKE I WANT IT TO!!
}
}
} // end of void function
};
Rather than checking the type you could simply add a virtual function to the class 'Base' and call that. This would simplify void functionAddDerivedToList(*Base myInputPtr) to the following:
void functionAddDerivedToList(*Base myInputPtr)
{
if((indexForDyanmicList + 1) < MAX_ARRAYSIZE) {
myDerived1And2DynamicList[indexForDyanmicList+1] = myInputPtr->clone();
}
}
Clone would always be implemented to call the class's copy constructor. So in Base, add the following:
virtual Base* clone() = 0;
The implementation would always take this form (example is for Derived1, a subclass of Base in your example):
virtual Base* clone() { return new Derived1(*this); }
One problem I see is that you are sing C-style array to contain a list of "Base" objects. Note that the size of the elements in the array in this case will be the sizof(Base), which is different with sizeof(Derived1) and sizeof(Derived2). Both derives may be different as well. What you can do in this case is to have the array contain pointers of Base objects instead of the actual objects. That will make the size uniformed to 4 bytes and you can access the objects in your array as pointers. Because the array now contain pointers you do not have to determine the type if you simply want to insert them in the array.
void functionAddDerivedToList(Base* myInputPtr)
{
if((indexForDyanmicList + 1) < MAX_ARRAYSIZE)
myDerived1And2DynamicList[indexForDyanmicList+1] = myInputPtr;
}
If you want to access the object from the array you can do something like this.
Base* p = myDerived1And2DynamicList[index];
p->MyMethod();
You can trust that the correct MyMethod function will be called based on the actual type of p in this case.
I have a class (UsingClass) that maintains a dynamic list of Base class pointers.
Sorry, but you have not (wrong syntax). But don't go that way.
First, give your Base class a virtual destructor. Otherwise you will experience memory leaks.
Then, redesign your UsingClass container. Give it a vector of shared_pointer to Base member to hold dynamically alocated polymorphic objects. (If you use a non C++0x-compiler, you can use std::tr1::shared_ptr.)
class UsingClass {
private:
std::vector<std::shared_ptr<Base> myList;
// int indexForDynamicList; is now myList.size()
public:
void Add(Base* myInputPtr) {
myList.push_back(myInputptr);
}
// ...
};
To add polymorphic objects, use
UsingClass container;
container.add(new Base);
container.add(new Derived1);
container.add(new Derived2);
You can call all polymorphic methods by iterating
for (size_t i = 0; i < myList.size(); ++i)
{
myList->functionM(); // give the function a more "speaking" name
}
By using shared_ptr you can hold many pointers to one object and don't have to care about freeing memory. Copying the pointers will not copy objects (so called shallow copy). If you really need to copy objects also (so called deep copy), your Base and derived classes will have to implement a virtual clone() method.
Suppose I have something like this:
class Father {
public:
virtual int genericMethod (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
};
class Son2: public Father {
public:
int genericMethod ()
{ }
int specifClassMethod()
{ }
};
In the main I do the following:
Father * test = new Son2();
test->specifClassMethod(); //Can't do this! It is specific of Class Son2 and is not a virtual method in class Father!
The main question here is to know the better way to access Son2 specific method through Father interface. I want to know if there is a Design Pattern to solve this or another way. I don't wanna to do casts and I don't wanna to put lots of 'if' in my code.
Regards,
Eduardo
Maybe the Visitor-Pattern is the pattern you're looking for.
How Visitor Pattern avoid downcasting
Possible approach is to have specific interface with optional methods, and virtual method to get this interface in the base class (which may return zero):
class SpecificInterface {
public:
virtual ~SpecificInterface()
{ }
virtual int specifClassCmethod() = 0;
{ }
};
class Father {
public:
virtual int genericMethod (void) = 0;
virtual SpecificInterface* getSpecificInterface (void) =0;
};
class Son1: public Father {
public:
int genericMethod ()
{ }
SpecificInterface* getSpecificInterface (void)
{ return 0; }
};
class Son2: public Father, public SpecificInterface {
public:
int genericMethod ()
{ }
int specifClassCmethod()
{ }
SpecificInterface* getSpecificInterface (void)
{ return this; }
};
Usage is following:
Father * test = new Son1();
SpecificInterface * specificAPI = test->getSpecificInterface();
if( specificAPI )
specificAPI->specifClassCmethod();
You couldn't legally solve this with a cast, either, because "test" is pointing to a Father object, not a Son2 object. Casting object types means "Trust me, compiler, this variable actually holds X". It doesn't somehow magically convert a base object into a derived object; it only tells the compiler something you already know that it does not.
If you want behavior that differs by derived class, then move the behavior into a virtual method -- i.e., the code that wants to call specificCLassMethod() belongs in a virtual method of Father.
No. To call methods which only exist in a child class, you'll have to cast to the ch ild class.
While you could create a map which maps function names to functions, add your functions to it from the child class' constructor and then use something like test->callMethod("name"); you'd have to make all those methods have the same signature or use varargs to pass arguments which is not very nice.
You can static_cast<Son2*>(test)->specifClassCmethod(); but that only works if Father * test = new Son2();
If you really have something specific to Son2 then dynamic_cast<> is what you should use. If it is something that could be added as a virtual function to the base class with a default empty behaviour, then you can solve your issue without a cast (but that is not what you wanted to do as you stated in the question)
One design pattern to solve your issue is to use a proxy object. That object would have all the methods susceptible to be called and delegate them to the real object or not.
Advantages of the proxy pattern:
you concentrate the logic needed to differentiate the objects behind to one place
you can add some logging easily
the client code remains simple and the Son classes clean from extra stuff
First of all,you can not create an instance for the class "Father" because it is an abstract class(which has virtual int genericMethod (void) =0; -pure virtual function).Instead an instance can be assigned to it....
Like
Son1* obj_son = new Son1();
Father* obj = obj_son;
//now if you call generic method - son1 method will be called(Father method is over ridden)
obj->genericMethod();
//similarly for son2 class
Son2* obj_son2 = new Son2();
Father* obj2 = obj_son2;
obj2->genericMethod();
obj2->specifClassCmethod();
I have a vector with pointers of type Vehicle. Vehicle is the base class and there are many derived types like MotorCycle, Car, Plane, etc. Now, in my program there comes a point where I need the derived type while traversing the vector. Each Vehicle class has a GetType() function which returns an int which tells me what the derived type is (motorcylce, car, plan). So, I can use a dynamic cast to downcast to the derived type from the base class pointer. However, I need to have a giant if statement everytime I need the derived pointer
if(vehicle_ptr->GetType() == PLANE)
Plane *ptr = dynamic_cast<Plane*> vehicle_ptr;
else if (vehicle_ptr->GetType() == MOTORCYCLE)
MotorCycle *ptr = dynamic_cast<MotorCycle*> vehicle_ptr;
..and on and on.
Is there a way to have a function or some trick I can call that would save me from the giant if statement everywhere? Like ::GetDerivedPtr(Vehicle *ptr). Would a template class help here? (never used them before) Sorry, my C++ is a bit rusty and I did search but these terms bring up too much material to find what I'm looking for. Thanks.
It looks like you've manually tried to recreate polymorphism. You don't need a type member. This is almost always a bad idea. Use polymorphism and virtual functions.
When you have a vehicle pointer v and do
v->function();
It will call the proper function for whatever type (Plane, Train, or Automobile) that the pointer actually points to if function is a virtual function. What you're doing is already handled by the language.
So:
class A {
public:
virtual void f() {cout << "A";}
};
class B : public A {
public:
virtual void f() {cout << "B";}
};
int main(){
A *a;
B b;
a = &b;
a->f();
}
The above snippet will print B.
I second the idea that you need some virtual function and a common base type. Imagine that there is some way to get the pointer which has the correct type. What will you do with it then? You'll have to make a giant switch anyway, because you call specific functions for each of your specific types.
One solution would be to invent a name for the operation you are trying to execute, and put its implementation as a virtual function at each specific Vehicle class. If the operation accepts different parameter for each of the cases, the parameters have to be packed into a special polymorphic structure/class, but here maybe the Visitor pattern is a more generic solution.
First check whether what you're going to do can be done simply via virtual functions in class Vehicle, overridden by each derived class.
If not, then consider the Visitor Pattern.
Cheers & hth.,
dynamic_cast will check the type itself (you don't need your own variable for this). You can do the following instead:
Plane *plane_ptr = dynamic_cast<Plane*>(vehicle_ptr);
if(plane_ptr != NULL)
{
// Do stuff with 'plane_ptr' that you couldn't do with 'vehicle_ptr'
}
I don't really see how creating a function to do the cast would help because you still need to class specific code anyway (and the function would have a fixed return type, so the closest you could get is something like the 'dynamic_cast' call, which is pretty much a standard function anyway).
Use Visitor based dispatching. Observe that not a simple cast of any kind is required in the follwing (somewhat trivialized) example:
// simple cyclic visitor
class VehicleVistor {
public:
// add overload for each concrete Vehicle type
virtual void Visit(class Motorcycle&) {};
virtual void Visit(class Plane&) {};
virtual void Visit(class Car&) {};
};
class Vehicle {
public:
virtual Accept(VehicleVisitor&) = 0;
};
class Car : public Vehicle {
public:
virtual Accept(VehicleVisitor& pVisitor) {
pVisitor.Visit(*this);
}
};
// and so on...
At some point of you program you need to retrieve all instances of, say Motorcycle:
class MotorcycleExtractingVisitor : public VehicleVisitor {
std::vector<Motorcycle*> mMotorcycles;
public:
void operator()(Vehicle* pVehicle) {
pVehicle->Accept(*this);
}
void Visit(Motorcycle& pMotorcycle) {
mAllMotorcycles.push_back(pMotorcycle);
}
std::vector<Motorcycles*> Get() { return mAllMotorcycles; }
};
class Extractor {
public:
// here you extract motorcycles
static std::vector<Motorcycle*> ExtractMotorcycles(std::vector<Vehicle*>& pVehicles) {
MotorcycleExtractingVisitor tMotos;
std::for_each(pVehicles.begin(), pVehicles.end(), tMotos);
return tMotos.Get();
}
// this would be a templatized version, left as exercise to the reader
template<class TExtracted, classtypename TBegItr, typename TEndItr>
static std::vector<TExtracted*> Extract(TBegItr pBeg, TEndItr pEnd) {
ExtractingVisitor<TExtracted> tRequiredVehicles;
std::for_each(pBeg, pEnd, tRequiredVehicles);
return tRequiredVehicles.Get();
}
};
Usage is as follows:
// fixed type version:
std::vector<Motorcycles*> tMotos =
Extractor::Extract(tVehicleVector);
// templatized version (recommended)
std::vector<Motorcycles*> tMotos =
Extractor::Extract<Motorcycles>(
tVehicleVector.begin(),tVehicleVector.end());