derived class pointer to base class object

R

Rahul

Hi Everyone,

I was just playing around virtual functions and landed up with the
following,

class Base1
{
public: virtual void sample()
{
printf("base::sample\n");
};
};

class Derived1: public Base1
{
public: void sample()
{
printf("derived::sample\n");
};
};

int main()
{
Derived1 *ptr = reinterpret_cast<Derived1 *> (new Base1());
ptr->sample();
return(0);
}

this invokes the sample() of base version, but if i declare sample as
a ordinay (non-virtual) function, the sample() of derived class is
invoked. I'm wondering how? Can anyone help in this regard?

Thanks in advance!!!
 
V

Victor Bazarov

Rahul said:
I was just playing around virtual functions and landed up with the
following,

class Base1
{
public: virtual void sample()
{
printf("base::sample\n");
};
};

class Derived1: public Base1
{
public: void sample()
{
printf("derived::sample\n");
};
};

int main()
{
Derived1 *ptr = reinterpret_cast<Derived1 *> (new Base1());
ptr->sample();
return(0);
}

this invokes the sample() of base version, but if i declare sample as
a ordinay (non-virtual) function, the sample() of derived class is
invoked. I'm wondering how? Can anyone help in this regard?

The code 'ptr->sample()' has undefined behaviour because casting from
a base class to a derived class is NOT what 'reinterpret_cast' is for.
Either 'static_cast' or 'dynamic_cast' are used for that.

In your case 'dynamic_cast' should return NULL since the object is
NOT of type 'derived', which should suggest that 'static_cast' is not
what you need either. You only use 'static_cast' in this situation
if you *know exactly* that the pointer was obtained by converting
some derived class object into the base.

V
 
P

Pete Becker

The code 'ptr->sample()' has undefined behaviour because casting from
a base class to a derived class is NOT what 'reinterpret_cast' is for.
Either 'static_cast' or 'dynamic_cast' are used for that.

In your case 'dynamic_cast' should return NULL since the object is
NOT of type 'derived', which should suggest that 'static_cast' is not
what you need either. You only use 'static_cast' in this situation
if you *know exactly* that the pointer was obtained by converting
some derived class object into the base.

And just to complete the circle: replacing reinterpret_cast with
static_cast in the original code still results in undefined behavior.
 
R

Rahul

The code 'ptr->sample()' has undefined behaviour because casting from
a base class to a derived class is NOT what 'reinterpret_cast' is for.
Either 'static_cast' or 'dynamic_cast' are used for that.

In your case 'dynamic_cast' should return NULL since the object is
NOT of type 'derived', which should suggest that 'static_cast' is not
what you need either. You only use 'static_cast' in this situation
if you *know exactly* that the pointer was obtained by converting
some derived class object into the base.

V

Then, how do you suggest to type cast from Base class object to
derived class pointer?
 
V

Victor Bazarov

Rahul said:
Then, how do you suggest to type cast from Base class object to
derived class pointer?

I am not really sure how to tell you this... Have you been reading
what I wrote? You can only do it using 'dynamic_cast' or 'static_cast'.
However, in your case, since the object you originally create is NOT
of the derived class, 'dynamic_cast' will fail (return NULL) and
'static_cast' has undefined behaviour.

*I suggest* you _don't_ cast the pointer to the base class to
a pointer to derived class when there is *no reason for it*.

If you need an object of the derived class, create an object of that
type. Then you can convert its address to the pointer of the base
class and later 'static_cast' it back to the same derived class.

What is the problem you're trying to solve?

V
 
A

Andrey Tarasevich

Rahul said:
...
Then, how do you suggest to type cast from Base class object to
derived class pointer?

If all you have is a standalone base class object (as in your original
code sample), then you sinly DON'T cast it to the derived type. Why on
earth would you want to do something like that?

If, on the other hand, you have a pointer to a base class _subobject_
within an object of derived class, then you can downcast that pointer
using 'static_cast' or 'dynamic_cast'.
 
C

Christopher

[snip]
Then, how do you suggest to type cast from Base class object to
derived class pointer?


Let me try and clarify the problem. Suppose Derived class has some
data in it like int x. Suppose Base class does not. Now:

you create an instance of the base class
you want a pointer to derived class
so, you tryed to cast a pointer from base to derived

Now STOP: Ask how is the compiler (or the program at run time)
supposed to know what to set int x to? It has no idea! That is the
source of your problem in attempting to cast in the wrong direction.

A derived class does not have everything it needs to make a base
class, but a base class only has "part" of what a derived class needs.

Because, most of the time the entire purpose of making a derived class
is to EXTEND the base. thusly, by extending, you add new things.

Now, if you really needed to cast from base to derived for some
reason, then you would need to implement some "factory" or method to
which additional data (if it exists in derived) can be supplied and
implement some logic to have it return an instance of the desired
type. Not a casted pointer, but more likely a new instance or a
pointer to a new instance.
 
C

Christopher

[snip
A derived class does not have everything it needs to make a base
class, but a base class only has "part" of what a derived class needs.
[snip]

edit typo: A derived class DOES have everything it needs to make a
base class, but a base class only has "part" of what it needs to make
a derived class.
 
A

anon

Rahul said:
I was just playing around virtual functions and landed up with the
following,

class Base1
{
public: virtual void sample()
{
printf("base::sample\n");
};
};

Besides other comments this base class is missing a virtual destructor.
 
Y

yurec

Hi Everyone,

I was just playing around virtual functions and landed up with the
following,

class Base1
{
public: virtual void sample()
{
printf("base::sample\n");
};
};

class Derived1: public Base1
{
public: void sample()
{
printf("derived::sample\n");
};
};

int main()
{
Derived1 *ptr = reinterpret_cast<Derived1 *> (new Base1());
ptr->sample();
return(0);

}

this invokes the sample() of base version, but if i declare sample as
a ordinay (non-virtual) function, the sample() of derived class is
invoked. I'm wondering how? Can anyone help in this regard?

Thanks in advance!!!

In first case (with virtual method) both classes have pointer to
virtual method table.
With reinterpret_cst you say to compiler to work with Base, as it has
memory layout as Derived class.
When you call ptr->sample() you do following :
1)get pointer to virtual table of the class ( which has the same place
in the object memory for Base and Derive, but different value)
2)call the first ( as Derived has single virtual method as Base does)
method from virtual table, which is Base::Sample.

If you remove virtual method from base class, both will not have any
pointer to virtual method table.So
When you call ptr->sample() you do following :
1)Get the address of Derived::sample and run it successfully, because
it doesn't refer to any of Derived members or methods

P.S. Some assumptions regarding second step, correct me please, if i'm
wrong :
There is special table for Derived methods ( for non virtual methods).
When you call ptr->sample(), you go to that table, find appropriate
function and give to this
function pointer to Base class as a parameter.
 
V

Victor Bazarov

yurec said:
I want to know waht do you think about my assumptions.Are they
correct?

At least one of them isn't: you assume we remember what you
posted about.

If you want to ask a follow-up question, quote enough of the
original discussion so at least some context is retained.

V
 
Y

yurec

At least one of them isn't: you assume we remember what you
posted about.

If you want to ask a follow-up question, quote enough of the
original discussion so at least some context is retained.

V
--







In first case (with virtual method) both classes have pointer to
virtual method table.
With reinterpret_cst you say to compiler to work with Base, as it has
memory layout as Derived class.
When you call ptr->sample() you do following :
1)get pointer to virtual table of the class ( which has the same place
in the object memory for Base and Derive, but different value)
2)call the first ( as Derived has single virtual method as Base does)
method from virtual table, which is Base::Sample.

If you remove virtual method from base class, both will not have any
pointer to virtual method table.So
When you call ptr->sample() you do following :
1)Get the address of Derived::sample and run it successfully, because
it doesn't refer to any of Derived members or methods

P.S. Some assumptions regarding second step, correct me please, if i'm
wrong :
There is special table for Derived methods ( for non virtual methods).
When you call ptr->sample(), you go to that table, find appropriate
function and give to this
function pointer to Base class as a parameter.- Hide quoted text -

- Show quoted text -
 
V

Victor Bazarov

yurec said:
I want to know waht do you think about my assumptions.Are they
correct?

[..]
In first case (with virtual method) both classes have pointer to
virtual method table.

That's something that is not defined by the language. You are free
to assume that, of course, but then you're in implementation-specific
area.

....about which the Standard explicitly says that the result of such
conversion is unspecified ([expr.reinterpret.cast]/7).

Going into how things are implemented... The "special table" only
exists during compilation/linking. After the program has been
built, there is no "special table for Derived methods". All calls
have been statically resolved to fixed addresses in memore (for
non-inlined calls) or inlined.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top