Skip to main content
gamedev.net
🔒 Locked

Virtual Constructors

Started by GamerSg Jan 1, 2004 at 3:30 AM 11 replies 700+ views
Darkor
Darkor
By that statement you are creating an array of 10 Fish instances? Whatever the case, it will call the constructors of both Animal and Fish, default constructors if there aren''t any you defined.

I''m not sure how you it didn''t register in your debugger. How did you perform the test?
Emonious
Emonious
Should register some output.. :/ Try a simple std::cout << "Constructor called"; if you haven''t already.
-----------------------------Naze ga muzukashi desu ka...
DrPizza
DrPizza
quote:
Animal* swordfish = new Fish[10];

Do not do this.

An array of derived class is not an array of base class; it''s an unfortunate trait of C (and hence C++) that no type distinction is made between "pointer to single object" and "pointer to array of objects".

char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;} /*** drpizza@battleaxe.net ***/
Sneftel
Sneftel
The better way would be an array (or, even better, a STL container) of pointers.


"Sneftel is correct, if rather vulgar." --Flarelocke
DrPizza
DrPizza
quote:
Original post by GamerSg
Isnt this polymorphism?

For a single objects, yes, it's one form of polymorphism.

For an array of objects, no, it's a bug waiting to happen. The reason is that the compiler will use offsets in terms of sizeof(Animal) and this will break if sizeof(Fish) is larger than sizeof(Animal).

quote:
What if i need the advantages of both polymorphism and dynamic memory allocation?

Then you should use something such as a std::vector<Animal*>, though you've then gotta be careful about memory management; some form of smart pointer, such as boost::shared_ptr, may be preferred. We could use an Animal**, thus:

Animal** zoo(new Animal*[10]); // I have a feeling that VC++ 7.0 and 7.1 will choke on this valid line, so change it to the assignment-looking form if you wish
for(int j(0); j < 10; ++j)
{
zoo[j] = new Fish;
}

but in general we don't like to use raw arrays like that, because they create more work for us.


[edited by - DrPizza on January 2, 2004 2:15:55 AM]
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;} /*** drpizza@battleaxe.net ***/
GamerSg
GamerSg
Hmm, so it is perfect if it only points to 1 object. Ok i''ll try to work around it.

But just out of curiosity, what would have happened if i had deleted the arrays.

class Animal
//My Animal destructor is virtual

class Fish : public Animal



Animal* swordfish = new Fish[10];



delete[] swordfish;

Would this call my Fish destructor for all the 10 objects?
kumikana
kumikana
The constructor of the parent is called only if it is called manualy by the child class in its constructor.

Example:
class Animal;

class Fish : public Animal
{
Fish() : Animal() { } // This way the Animals constructor will be called

};



CraZeE
CraZeE
kumikana: i may be wrong on correcting you, but if i'm not then the base class constructor is always called by default if its not done explicitly. the only cathc is that only the default (non-overloaded) constructor is called. In that sense u're example code need not be done coz thats wat actually happens. If the base class has an overloaded constructor which accepts parameters, then it is called only if called explicitly in the child class constructor initialization list. Eg:


class Animal;

class Fish : public Animal
{
Fish() : Animal() { } // This way is kinda redundant though not wrong

};


more useful would be:

class Animal;

class Fish : public Animal
{
Fish() : Animal(4) { } // This way the Animals constructor will be called with special parameters as needed.

};


[edited by - crazee on January 2, 2004 9:26:26 AM]
To learn, we share... Give some to take some -
emileej
emileej
Your correction is justified. The default constructor of the inherited class is always called. The real power of calling the parent constructor is this:

class Animal{
Animal(string type,int age){
buff[10];
itoa(age,buff,10);
cout << buff << " year(s) old " << type.c_str() << "created\n";
}
};

class Fish:public Animal{
Fish(int age):Animal("fish",age);
};


"Stop trying to hit me and hit me!"
Emil Johansen- SMMOG AI designerhttp://smmog.com
Greatwolf
Greatwolf
quote:
Original post by GamerSg
Animal* swordfish = new Fish[10];


delete[] swordfish;

Would this call my Fish destructor for all the 10 objects?


You''ll probably need to make your base destructor virtual in this case or delete''s gonna think you''re deleting an animal object and skip calling the fish destructor. Other then that, yes the destructor should be invoked 10 times here.





--{You fight like a dairy farmer!}
--{You fight like a dairy farmer!}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.