• Advertisement

Archived

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

casting up and casting down.

This topic is 5098 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

I just read some stuff on casting. It covered the data slicing problem. Where casting up causes the loss of data that is in the descendent object; however, the problem can be somewhat avoided by using a pointer rather than variable assignment and virtual funcations (or something along those lines.) My question is: how do you actually move the other way, from an ancestor to a descendent. Since in the same text it says that casting down is dangerous...and complicated, and so forth...what gives? Sorry I don''t have any code to go along with my question, but I was hoping someone could just throw me a bone here and maybe explain it a little more concisely. thanks, L-

Share this post


Link to post
Share on other sites
Advertisement
Say you've got a base class A like this:


class A
{
public:

virtual void AFunction();

};


Now suppose you derive a class B from A...


class B : public A
{

public:

virtual void BFunction();

};


In this example, B has two functions: AFunction() and BFunction(), but A only has one, the AFunction().

Suppose we'd do something like this:


A a;
B b;
a = b; // assign b to a, slicing
//...
b.AFunction(); // this will work
b.BFunction(); // this will work
a.AFunction(); // this will work
a.BFunction(); // this will *not* work; error!


Why won't a.BFunction() work? Simple, a is an instance of class A, and class A doesn't have a BFunction(). And that's why 'casting down' is dangerous.

If you'd do this with pointers, it would work (see dynamic binding @ google).

That's a simple explanation.


[edited by - EL on February 6, 2004 1:35:30 PM]

Share this post


Link to post
Share on other sites
It sounds like down casting is nigh-impossible, or rather frowned upon entirely. Isn''t this something of limitation? Is there a good work around. I suppose keeping pointers to both the Ancestor and the derived class is how you might use both. The reason I say this is that some function might only accept a pointer to a derived class rather then the ancestor class -- and the same goes for abstract classes/interfaces.

Any suggestions or comments here?

L-

Share this post


Link to post
Share on other sites
Down-casting is dangerous just because you are assuming something that might be false, you''re assuming that this object actually is an instance of the subclass. And of course if you''re wrong, disaster ensues.

But that doesn''t mean you should never do it, there are certainly situations where it would work fine.

An OO purist would tell you that the way you should do it is: if you are downcasting to B so that you can call BFunction(), then you should define BFunction as virtual in class A, and then override it in class B. Then you just call BFunction; no casting necessary.

Share this post


Link to post
Share on other sites
Alright that sounds reasonable -- no blindly down casting. I mean that makes sense. It seems sort of obvious though. Alright -- so this means that if you have an object cast to some type of interface and you pass this opject to a method that calls a method of that interface and then return the object and then recast it to its original descendent level -- everything should be fine, right?

L-

Share this post


Link to post
Share on other sites
In case you still need to downcast.


// your classes

class Base
{
public:
virtual ~Base(){}
};

class Derived : public Base
{
};

Base* pBase;
Derived* pDerived;


// somewhere in your code

pDerived = dynamic_cast< Derived* >( pBase );

if( pDerived ){
// do your stuff with pDerived

}
else{
// pBase did NOT point to an instance of class Derived

}



This works because dynamic_cast only returns a valid pointer if the pointer your trying to downcast points to an instance the type your trying to downcast a pointer to. Otherwise it returns NULL.
Limitation is that your classes must have at least one virtual method. ( the virtual destructor in this case )
Also this method has a small performance penalty because at runtime the vtable must be looked up, to see if it is a valid downcast.

Edit: typo

[edited by - Direct4D on February 6, 2004 4:31:53 PM]

Share this post


Link to post
Share on other sites

  • Advertisement