By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,385 Members | 1,737 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,385 IT Pros & Developers. It's quick & easy.

Question on dynamic binding

P: n/a
Hi,

I've following code :

class Base {
public:
virtual void func() { std::cout << "Base" << std::endl; }
};

class Derived : public Base {
public:
void func() { std::cout << "Derived" << std::endl; }
};

class MostDerived : public Derived {
public:
void func() { std::cout << "MostDerived" << std::endl; }
};

int main(int argc, char **argv)
{
Base *pBase = 0;
Derived *pDerived = 0;
try {
pBase = new MostDerived;
pDerived = new MostDerived;

if (pBase) {
pBase->func();
delete pBase;
pBase = 0;
}
if (pDerived) {
pDerived->func();
delete pDerived;
pDerived = 0;
}
} catch (...) {
if (pBase) delete pBase;
if (pDerived) delete pDerived;
}
return 0;
}

On execution, why the o/p is
MostDerived
MostDerived

I's expecting it to be

Derived
Derived

as after Derived, it's no longer virtual ... Please clarify me the
reasons ...

I've verified it with g++ and Sun compiler ... same behavior with both
the compiler ...

Regards,
~ Soumen

May 24 '07 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Soumen wrote:
Hi,

I've following code :

class Base {
public:
virtual void func() { std::cout << "Base" << std::endl; }
};

class Derived : public Base {
public:
void func() { std::cout << "Derived" << std::endl; }
};

class MostDerived : public Derived {
public:
void func() { std::cout << "MostDerived" << std::endl; }
};
___ snipped main ___

as after Derived, it's no longer virtual ... Please clarify me the
reasons ...

I've verified it with g++ and Sun compiler ... same behavior with both
the compiler ...

Regards,
~ Soumen
func is a virtual function in all three classes as in the derived
classes it is a valid override of a virtual function in a base class.
See the section [class.virtual] in the standard.

Charles.
May 24 '07 #2

P: n/a
Soumen <so******@gmail.comwrote:
class Base {
public:
virtual void func() { std::cout << "Base" << std::endl; }
};

class Derived : public Base {
public:
void func() { std::cout << "Derived" << std::endl; }
};

class MostDerived : public Derived {
public:
void func() { std::cout << "MostDerived" << std::endl; }
};

int main(int argc, char **argv)
{
Base *pBase = 0;
Derived *pDerived = 0;
try {
pBase = new MostDerived;
pDerived = new MostDerived;

if (pBase) {
pBase->func();
delete pBase;
pBase = 0;
}
if (pDerived) {
pDerived->func();
delete pDerived;
pDerived = 0;
}
} catch (...) {
if (pBase) delete pBase;
if (pDerived) delete pDerived;
}
return 0;
}

On execution, why the o/p is
MostDerived
MostDerived

I's expecting it to be

Derived
Derived

as after Derived, it's no longer virtual ... Please clarify me the
reasons ...
Once a function is declared as virtual, it will always be virtual in any
derived classes. You cannot un-virtualize a function like that. The
presence of the 'virtual' keyword in the derived class function
declaration is optional, however some people like to include it merely
as a reminder.
I've verified it with g++ and Sun compiler ... same behavior with both
the compiler ...
--
Marcus Kwok
Replace 'invalid' with 'net' to reply
May 24 '07 #3

P: n/a
Soumen wrote :
Hi,

I've following code :

class Base {
public:
virtual void func() { std::cout << "Base" << std::endl; }
};

class Derived : public Base {
public:
void func() { std::cout << "Derived" << std::endl; }
};

class MostDerived : public Derived {
public:
void func() { std::cout << "MostDerived" << std::endl; }
};

int main(int argc, char **argv)
{
Base *pBase = 0;
Derived *pDerived = 0;
try {
pBase = new MostDerived;
pDerived = new MostDerived;

if (pBase) {
pBase->func();
delete pBase;
That last statement yields UB, because Base doesn't have a virtual
destructor. If you plan to destroy objects via their base pointer,
always define a virtual destructor.

- Sylvester
May 24 '07 #4

P: n/a
On May 24, 10:37 am, Soumen <soume...@gmail.comwrote:
Hi,

I've following code :

class Base {
public:
virtual void func() { std::cout << "Base" << std::endl; }

};

class Derived : public Base {
public:
void func() { std::cout << "Derived" << std::endl; }

};

class MostDerived : public Derived {
public:
void func() { std::cout << "MostDerived" << std::endl; }

};

int main(int argc, char **argv)
{
Base *pBase = 0;
Derived *pDerived = 0;
try {
pBase = new MostDerived;
pDerived = new MostDerived;

if (pBase) {
pBase->func();
delete pBase;
pBase = 0;
}
if (pDerived) {
pDerived->func();
delete pDerived;
pDerived = 0;
}
} catch (...) {
if (pBase) delete pBase;
if (pDerived) delete pDerived;
}
return 0;

}

On execution, why the o/p is
MostDerived
MostDerived

I's expecting it to be

Derived
Derived
No, its not since you've overridden the virtual function in
MostDerived.
>
as after Derived, it's no longer virtual ... Please clarify me the
reasons ...
This is incorrect, a virtual function is always virtual. The logic
here is that if you wanted Derived::func() to be called, then don't
override that virtual function in MostDerived or explicitly call
Derived::func() from MostDerived::func().
>
I've verified it with g++ and Sun compiler ... same behavior with both
the compiler ...

Regards,
~ Soumen
By the way, your Base dtor should be virtual (which would also imply
that derivative dtors will also be virtual).
delete pBase; // is a memory leak otherwise.

May 24 '07 #5

P: n/a
On May 24, 8:53 pm, Salt_Peter <pj_h...@yahoo.comwrote:
On May 24, 10:37 am, Soumen <soume...@gmail.comwrote:
Hi,
I've following code :
class Base {
public:
virtual void func() { std::cout << "Base" << std::endl; }
};
class Derived : public Base {
public:
void func() { std::cout << "Derived" << std::endl; }
};
class MostDerived : public Derived {
public:
void func() { std::cout << "MostDerived" << std::endl; }
};
int main(int argc, char **argv)
{
Base *pBase = 0;
Derived *pDerived = 0;
try {
pBase = new MostDerived;
pDerived = new MostDerived;
if (pBase) {
pBase->func();
delete pBase;
pBase = 0;
}
if (pDerived) {
pDerived->func();
delete pDerived;
pDerived = 0;
}
} catch (...) {
if (pBase) delete pBase;
if (pDerived) delete pDerived;
}
return 0;
}
On execution, why the o/p is
MostDerived
MostDerived
I's expecting it to be
Derived
Derived

No, its not since you've overridden the virtual function in
MostDerived.
as after Derived, it's no longer virtual ... Please clarify me the
reasons ...

This is incorrect, a virtual function is always virtual. The logic
here is that if you wanted Derived::func() to be called, then don't
override that virtual function in MostDerived or explicitly call
Derived::func() from MostDerived::func().
Thanks ... that means once at least one function in any class is
virtual, any class
derived from it start having a separate _vtable.
Now say func() wasn't virtual in Base. I made it virtual only in
Derived. So I think
there'll not be any Base::_vtable but there'll be Derived::_vtable and
MostDerived::_vtable.
Is my understanding is correct?

>
By the way, your Base dtor should be virtual (which would also imply
that derivative dtors will also be virtual).
delete pBase; // is a memory leak otherwise.
How could there be leak in this case? Though I admit if Base is
designed to be used as
base class, the dtr should be virtual.

Thanks again to all who clarified it.

Regards,
~ Soumen

May 24 '07 #6

P: n/a
On May 24, 9:40 pm, Soumen <soume...@gmail.comwrote:
On May 24, 8:53 pm, Salt_Peter <pj_h...@yahoo.comwrote:
On May 24, 10:37 am, Soumen <soume...@gmail.comwrote:
Hi,
I've following code :
class Base {
public:
virtual void func() { std::cout << "Base" << std::endl; }
};
class Derived : public Base {
public:
void func() { std::cout << "Derived" << std::endl; }
};
class MostDerived : public Derived {
public:
void func() { std::cout << "MostDerived" << std::endl; }
};
int main(int argc, char **argv)
{
Base *pBase = 0;
Derived *pDerived = 0;
try {
pBase = new MostDerived;
pDerived = new MostDerived;
if (pBase) {
pBase->func();
delete pBase;
pBase = 0;
}
if (pDerived) {
pDerived->func();
delete pDerived;
pDerived = 0;
}
} catch (...) {
if (pBase) delete pBase;
if (pDerived) delete pDerived;
}
return 0;
}
On execution, why the o/p is
MostDerived
MostDerived
I's expecting it to be
Derived
Derived
No, its not since you've overridden the virtual function in
MostDerived.
as after Derived, it's no longer virtual ... Please clarify me the
reasons ...
This is incorrect, a virtual function is always virtual. The logic
here is that if you wanted Derived::func() to be called, then don't
override that virtual function in MostDerived or explicitly call
Derived::func() from MostDerived::func().

Thanks ... that means once at least one function in any class is
virtual, any class
derived from it start having a separate _vtable.
Now say func() wasn't virtual in Base. I made it virtual only in
Derived. So I think
there'll not be any Base::_vtable but there'll be Derived::_vtable and
MostDerived::_vtable.
Is my understanding is correct?
By the way, your Base dtor should be virtual (which would also imply
that derivative dtors will also be virtual).
delete pBase; // is a memory leak otherwise.

How could there be leak in this case? Though I admit if Base is
designed to be used as
base class, the dtr should be virtual.

Thanks again to all who clarified it.

Regards,
~ Soumen
The reason for memory leak is non virtual destructor. When you will
call delete pBase; it will just call base class destructor (as
destructor is non virtual so no polymorphism) and any memory allocated
in the derived classes will never be deallocated.

Regards
Vineet

May 25 '07 #7

P: n/a
On 24 Maj, 18:40, Soumen <soume...@gmail.comwrote:
On May 24, 8:53 pm, Salt_Peter <pj_h...@yahoo.comwrote:
On May 24, 10:37 am, Soumen <soume...@gmail.comwrote:
[snip]
>
By the way, your Base dtor should be virtual (which would also imply
that derivative dtors will also be virtual).
delete pBase; // is a memory leak otherwise.

How could there be leak in this case? Though I admit if Base is
designed to be used as
base class, the dtr should be virtual.
A leak is only one possible outcome. The standard requires your
destructor to be virtual whenever you delete an object via a pointer
to its baseclass, causing undefined behaviour if it is not. In
practice, the result will often be a leak although it sometimes - as
in your example - just seems to work.
Normally, when a class has virtual functions you should declare the
destructor virtual. My recommendation is to always declare it so,
removing the virtual destructor in those cases where your analysis
tells you it is not needed.

/Peter
>
Thanks again to all who clarified it.
May 25 '07 #8

P: n/a
On May 24, 5:53 pm, Salt_Peter <pj_h...@yahoo.comwrote:
On May 24, 10:37 am, Soumen <soume...@gmail.comwrote:
[...]
By the way, your Base dtor should be virtual (which would also imply
that derivative dtors will also be virtual).
delete pBase; // is a memory leak otherwise.
It's undefined behavior otherwise. In fact, I don't think I've
actually seen a case where it was a memory leak (although it's
certainly possible); I have seen core dumps because of it,
however. Most of the time, however, it works fine in all of
your tests, only to core dump dramatically when you do the demo
for your most important client. (Seriously: most of the time,
it works with single inheritance, but corrupts the free space
arena when multiple inheritance is involved, so you get some
strange error further down the road, in totally unrelated code.)

--
James Kanze (GABI Software) email:ja*********@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

May 25 '07 #9

This discussion thread is closed

Replies have been disabled for this discussion.