Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Scint

Inheritance and Double Pointers

This topic is 5299 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Let's say you have a base class Cat, and an inherited class Tiger. The virtual function for use is Meow(). This is perfectly fine:
Cat *pCat;
Tiger *pTiger = new Tiger;
pCat = pTiger;
pCat->Meow(); //uses tiger's meow

But this is not:
Cat **ppCat;
Tiger **ppTiger = new Tiger*[MAX_TIGERS]; 
//(then allocate for each ptr...)

ppCat = ppTiger; //COMPILE ERROR!

(*ppCat)->Meow();
Anybody know why? HOWEVER... if replace the line in error with this:
ppCat = reinterpret_cast < Cat** > (ppTiger);
(*ppCat)->Meow();
...the meow called will be tiger's meow. Edit: source-ified [edited by - Scint on April 16, 2004 1:43:34 AM]

Share this post


Link to post
Share on other sites
Advertisement
Because a pointer to a pointer to derived is not convertable to a pointer to a pointer to base. In other words, a Tiger array is not convertable to a Cat array, and adding a pointer doesn''t change that.

A warning - while the initial thing you wrote did work, the following will not:
ppCat[1]->Meow();
Because it will use the size of a Cat, rather than the size of a tiger to index into the array. So you''ll end up with
this 
pointing to half of two tiger objects.


May I suggest a different approach?

#include <vector>
using std::vector;
class Cat;
class Tiger : Cat;
vector<Tiger*> tigers;
//fill up tigers

tigers.push_back(new Tiger());
tigers.push_back(new Tiger());

vector<Cat*> cats(tigers.begin(),tigers.end()); //use a range constructor, which will copy every element of tigers into cats

for(int i=0; i < cats.size(); i++)
{
cats[i]->Meow();
}

Share this post


Link to post
Share on other sites

Cat **ppCat;
Tiger **ppTiger = new Tiger*[MAX_TIGERS];
//(then allocate for each ptr...)

ppCat = ppTiger; //COMPILE ERROR!

(*ppCat)->Meow();


Think about it this way: Pointers to base classes can point to objects of derived classes (nothing new here), but when you use double indirection, you specify the exact type the first level of indirection points to. To clarify, ppCat can only point to a pointer to cat (the first level), but *ppCat (the second level) is just a pointer to cat, so it can also point to derived classes.

Share this post


Link to post
Share on other sites
quote:
Original post by fallenang3l

Think about it this way: Pointers to base classes can point to objects of derived classes (nothing new here), but when you use double indirection, you specify the exact type the first level of indirection points to. To clarify, ppCat can only point to a pointer to cat (the first level), but *ppCat (the second level) is just a pointer to cat, so it can also point to derived classes.


I came across this issue when I had a function that needed a double pointer as a parameter, something like:


HRESULT Makebuffer( Bufferbase **ppBB, DWORD flags )
{
//...allocate memory stuff...

switch(flags) {
case FLAG1: *ppBB = new Flag1Buffer;
break;
//etc.

}
}

//Somewhere else...

Bufferbase *pBB;
Makebuffer( &pBB, flags );



...and on a whim one time I tried to pass in an inherited class instead of a base class.

In some experimenting I also discovered this:

   

void CatsMeow( Cat* pCat )
{
pCat->Meow();
}

void CatsMeowRef( Cat*& pCat )
{
pCat->Meow();
}

int main(void)
{
Cat *mycat = new Cat;
Tiger *mytiger = new Tiger; //tiger derived from cat


CatsMeow(mycat);//legal

CatsMeow(mytiger);//legal


CatsMeowRef(mycat); //legal

CatsMeowRef(mytiger); //illegal


return 0;
}



edit: typos...

[edited by - Scint on April 16, 2004 1:53:14 AM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!