A problem about virtual function?

W

Wayne Shu

Hi everyone,

Today I meet a problem about virtual function. Consider the
following little program.

#include <iostream>

class base
{
int i;
public:
virtual void print() { std::cout << "base" << std::endl; }
virtual ~base() {}
};

class derived : public base
{
public:
virtual void print() { std::cout << "derived" << std::endl; }
};

int main()
{
base b;
b::~base();

new (&b) derived;

(&b)->print(); // (1)
base *p = &b;
p->print();

return 0;
}

I have try the VC2005 Express Edition and GCC 3.4.2
and the result is :
base
derived

Why (1) statement print "base"?

thanks

Best Regards.
 
G

Guest

Hi everyone,

Today I meet a problem about virtual function. Consider the
following little program.

#include <iostream>

class base
{
int i;
public:
virtual void print() { std::cout << "base" << std::endl; }
virtual ~base() {}
};

class derived : public base
{
public:
virtual void print() { std::cout << "derived" << std::endl; }
};

int main()
{
base b;
b::~base();

new (&b) derived;

(&b)->print(); // (1)
base *p = &b;
p->print();

return 0;
}

I have try the VC2005 Express Edition and GCC 3.4.2
and the result is :
base
derived

Why (1) statement print "base"?

First, I am not sure if it is legal to call the destructor of an
automatic object and then construct a new object of a type derived from
the first object's type in the same place, it seems very suspect to me.

My *guess* of what is happening is this. First you create an object of
type base with automatic storage (on the stack). An object can never
have polymorphic behaviour (only a pointer/reference to an object), an
object always have a known type (even though it might not be known when
the program is compiled). More importantly, all objects on the stack
have a type which is know at compile-time.

So when you do (&b)->print() the compiler knows that the type of b is
base, and thus the only possible outcome of that line is a call to
base::print(). It is an optimisation, the compiler will try to not make
a virtual call if it does not have to since they involve an extra
indirection.

On the other hand when you create a pointer to the object and then call
print() on that all the compiler knows is that you call print() on a
pointer to base, the actual type of the object that the pointer points
to is not know and a virtual call must be made.
 
J

James Kanze

First, I am not sure if it is legal to call the destructor of
an automatic object and then construct a new object of a type
derived from the first object's type in the same place, it
seems very suspect to me.

I think it's undefined behavior; if it isn't, it should be. (To
start with, there's no guarantee that sizeof(derived) <=
sizeof(base).)
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top