|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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. |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On 2007-10-16 16:09, Wayne Shu wrote:
> 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. -- Erik Wikström |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Oct 16, 4:42 pm, Erik Wikström <Erik-wikst...@telia.com> wrote:
> On 2007-10-16 16:09, Wayne Shu wrote: > > 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. 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).) -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
![]() |
| Outils de la discussion | |
|
|