473,385 Members | 1,359 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Question on dynamic binding

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
8 1239
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
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
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: festiv | last post by:
Hi there, I want to learn how the compiler is implementing the dynamic binding. where can i read about this subject (the hole process). thanks.
3
by: prashna | last post by:
Hi all, Is'nt a function invocation through a function pointer is dynamic binding? For example consider the following program 1 int main() 2 { 3 int (*fun_ptr)(); 4 int...
5
by: enki | last post by:
I was reading a book on game programming and they were explaining a game engine class and they say that correct OO programming is making base calss functions virtual. I am been reading and larning...
9
by: Gibby Koldenhof | last post by:
Hiya, Terrible subject but I haven't got a better term at the moment. I've been building up my own library of functionality (all nice conforming ISO C) for over 6 years and decided to adopt a...
21
by: Tamir Khason | last post by:
Question regarding the architecture issues: I have 2 classes with the ALMOST SAME methods and properties, BUT inplmentation is completly different. I have to use one of those classes according...
3
by: compgeek.320 | last post by:
Hi Everyone, Can any one explain me about Dynamic binding related to OOPs concepts.I studied in a book that the polymorphic fuction call will be decided in the runtime rather than the compile...
7
by: Ryan | last post by:
I'm in the process of learning more about building my ASP.NET website to use my SQL datastore and am a bit confused about how ADO.NET works with ASP.NET. This Microsoft article implies that using...
4
by: wizwx | last post by:
The followings are a few lines of code from the Template method in "Thinking in C++" vol.2 pp.639 class ApplicationFramework { protected: virtual void customize1() = 0; virtual void...
0
by: ChopStickr | last post by:
I have a custom control that is embedded (using the object tag) in an html document. The control takes a path to a local client ini file. Reads the file. Executes the program specified in...
2
by: 09876 | last post by:
Hi: all I understand the difference between dynamic binding and static binding. But I just wonder what is the point to make the distinction between the dynamic binding and static binding. For...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.