Archived

This topic is now archived and is closed to further replies.

Virtual Functions

This topic is 5618 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When creating derived classes sometimes you have to use virtual functions so that your program will know the correct function to call. I have done this in the following code which uses stockitem as a base class, visualitem is derived from this class and then visualmusic is derived from visual item: Header Files: ============= STOCKITEM #if !defined(STOCKITEMH) #define STOCKITEMH #include <strng.h> class StockItem { protected: String stockNo; String description; int quantity; float price; public: StockItem(); StockItem(String sNo, String desc, int qty, float pr); ~StockItem(); void SetStockNo(String sNo); void SetDescription(String desc); void SetQuantity(int qty); void SetPrice(float pr); //Fuctions are const as they do not change the class in any way String GetStockNo() const; String GetDescription() const; int GetQuantity() const; float GetPrice() const; virtual void Display() const; }; #endif VISUALITEM #if !defined(VISUALITEMH) #define VISUALITEMH #include <strng.h> #include "StockItem.h" class VisualItem : public StockItem { private: String media; public: VisualItem(); VisualItem(String sNo, String desc, int qty, float pr, String med); ~VisualItem(); void SetMedia(String med); String GetMedia() const; void Display() const; }; #endif VISUALMUSIC #if !defined(VISUALMUSICH) #define VISUALMUSICH #include <strng.h> #include "VItem.h" class VisualMusic : public VisualItem { private: String artist; public: VisualMusic(); VisualMusic(String sNo, String desc, int qty, float pr, String med, String art); ~VisualMusic(); void SetVmusicArtist(String art); String GetVmusicArtist() const; void Display() const; }; #endif QUESTION As you can see I have made the Display() member function of the stockitem class a virtual function so that the the correct display function is called depending on the type of object created but should I also make the Display() member function of visualitem a virtual function since visualmusic is derived from this class, or is the way that I am currently using okay? Since it is not currently a virtual function does that mean that I am just overriding the function? How about them apples?

Share this post


Link to post
Share on other sites
Making a function virtual in a base class makes that function virtual all the way down the inheritance tree. You don''t need "virtual" in visualitem::Display(), but many programmers like to stick it in there anyway, as a reminder that it can be called as a virtual function.



Don''t listen to me. I''ve had too much coffee.

Share this post


Link to post
Share on other sites
quote:
Original post by popcorn
Why should the base destructor be virtual dobbs?

How about them apples?


Imagine this code:
StockItem* someItem = new VisualItem;
// you play around with someItem
delete someItem; // problem over here

The problem is that only StockItem''s destructor gets called. If you allocated any dynamic resources in VisualItem''s ctor, those resources will never be freed by the dtor because it will never get called. Or in other words, an ugly memory leak that can be hard to trace. So remember, if you want to make your class a base class, ALWAYS make the dtor virtual unless you have some STRONG reason to do otherwise and you know what you''re doing.

Share this post


Link to post
Share on other sites
Ummmm......

Ok, I am questioning myself now, so I'm going to test this to make sure. But you must put virtual in each base class that you want to propogate the virtual call. I've used this many times and actually got into an argument about it, but that was long ago. I'm almost positive that you need it in each base class, but now I'm going to test it to make sure.

Ok, someone else test this for me. I don't have a quick test.

Stephen Manchester
Senior Technical Lead
Virtual Media Vision, Inc.
(310) 930-7349
stephen@virtualmediavision.com

[edited by - smanches on July 25, 2002 2:15:36 PM]

Share this post


Link to post
Share on other sites
smanches tell us the results of your test but i think what sneftel said makes sense: that is a virtual function is propagated down the inheritance tree.

How about them apples?

Share this post


Link to post
Share on other sites
quote:
Original post by smanches
Ummmm......

Ok, I am questioning myself now, so I''m going to test this to make sure. But you must put virtual in each base class that you want to propogate the virtual call. I''ve used this many times and actually got into an argument about it, but that was long ago. I''m almost positive that you need it in each base class, but now I''m going to test it to make sure.

Ok, someone else test this for me. I don''t have a quick test.





  
#include <iostream>

using namespace std;

class A
{
public:
virtual void test()
{
cout << "A!\n";
}
};

class B : public A
{
public:
void test()
{
cout << "B!\n";
}
};

class C : public B
{
public:
void test()
{
cout << "C!\n";
}
};

int main()
{
C *c = new C;
B *b = c;
A *a = b;
a->test();
return 0;
}


Outputs "C!"



Don''t listen to me. I''ve had too much coffee.

Share this post


Link to post
Share on other sites
Thanks. I don''t know what I was thinking. I think I need more coffee.

Stephen Manchester
Senior Technical Lead
Virtual Media Vision, Inc.
stephen@virtualmediavision.com
(310) 930-7349

Share this post


Link to post
Share on other sites
quote:
Original post by smanches
I think I need more coffee.

A good decision, in any situation.

EDIT: seriously, tho, I know what you were thinking. C++ has so little syntactic sugar in the language that it's downright bizarre for the virtual keyword in a derived class not to have any effect whatsoever. I assume the option of the useless "virtual" was put in the language to assuage the ego of some committee member who wanted C++ to look more like his pet OO language.


Don't listen to me. I've had too much coffee.

[edited by - sneftel on July 25, 2002 6:39:40 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Sneftel
it''s downright bizarre for the virtual keyword in a derived class not to have any effect whatsoever.

It''s also useful in certain circumstances. Consider:


  
#include <iostream>

struct VirtualDtor
{
virtual ~VirtualDtor()
{}
};

struct StaticDtor
{
};

template<class DestructionPolicy>
struct Thing : public DestructionPolicy
{
void f()
{
std::cout << "f()" << std::endl;
}
};

class AggregatedThing
{
private:
Thing<StaticDtor> st;
};

class DerivedThing : public Thing<VirtualDtor>
{
};

int main()
{
AggregatedThing at;
DerivedThing dt;
}

Share this post


Link to post
Share on other sites