Archived

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

dynamicman

Effects of upCasting....

Recommended Posts

I would just like to understand more about the effects of upcasting.. lets say we have the following classes...
        

class base
{
     public:
          foo();
};

class child : public base
{
     public:
          foo();
          foo2();
};

  
Now, downcasting would be legal and nothing crazy will happen, for example..
  
      
child* mychild = new child();
base* mybase = (base*)child;
mybase->foo() //legal


  
but with direct upcasting, the memory does not align correctly, so it is illegal. Example of upcasting..
  
      
base* mybase = new base();
child* mychild = (child*)mybase;
mybase->foo2() //illegal


  
finally a safe upcast would be...
  

base* mybase = new child();
child* mychild = (child*)mybase;
mychild->foo2() //legal


  
My question regards to the final type of cast (the safe upcast). What really happens behind the scene with the cast? Does the memory try to align itself (like float/int)? Does it do any data miniuplation at compile time? Or is it just a gimmick at run-time to tell the compiler what methods and members are allowed to be accessed? I'm very confused at the overhead involved in doing an safe upcast. If it plays with memory, I'm sure it'll be kinda slow if its done many times in a tight loop. If it doesn't play with memory, would it be safe to say that the upcast has no overhead? thanks in advace! Edited by - dynamicman on October 16, 2001 11:26:41 PM

Share this post


Link to post
Share on other sites
A cast with no virtual members will have no overhead. It just tells the compiler what is a valid operation on the object that is being pointed to. When you have a base class pointer that points at a child object, the ''extra'' methods and members of the child class are still present, they are just inaccesible.

However, if you have virtual functions, there is a slight overhead to access and dereference the vtable. This really isn''t much of a hit though and can basically be ignored in most circumstances.

Share this post


Link to post
Share on other sites
sorry but... what do you mean "access and dereference" the vtable? Lets say we have virtual functions (say both foo() and foo2() are virtual)....

From what I understand, the child vtable will be created with the first creation.

  

base* mybase = new child();



but what happens to the cast? What does the "access and dereference" mean regarding to the vtable?


(in plain english please... kinda dumb on the tech jargon, sorry)

Share this post


Link to post
Share on other sites
I just spent three hours writing a program that is supposed to do this, but it doesn''t work I don''t seem to understand what I going on here either. Here is an analogy to what I''m trying to do:

  
base * Factory(unsigned int type_id)
{
base * mybase;
switch(type_id)
{
case CHILD:
mybase = new child;
return mybase;
default:
return NULL;
}
}

void MainCycle(void)
{
child * mychild = (child *)Factory(CHILD);
mychild->foo2();
}



This is basically the same thing, isn''t it? It isn''t working though. I keep getting a casting error saying that I can''t cast the base pointer to the child pointer. What''s going on here?

Paradigm Shift 2000

Share this post


Link to post
Share on other sites
You can''t cast from a base pointer to a child pointer. That''s totally unsafe anyway. We don''t know whether the base is simply a pointer to the child, actually IS a child just being referenced through a base pointer. Then there''s the sleezy way around it. static_cast. While it still is totally and completely unsafe and highly unrecommended, the compiler will shutup

Share this post


Link to post
Share on other sites
To dynamicman:

In your first post everything is ok, except for some details:
1) casting from child class to base class is called upcasting, not downcasting and vice versa, so

base* mybase = (base*)mychild;

is upcasting, but

child* mychild = (child*)mybase;

is downcasting.

2) When you are doing upcasting, you must write

child* mychild = new child;
base* mybase = mychild; // without (child*)

without explicit cast statement. If you write child* mychild = (child*)mybase, compiler will compile this even if child doesn't inherit from base.

Edited by - Advanced Bug on October 17, 2001 5:45:14 AM

Share this post


Link to post
Share on other sites