C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 07-12-2009, 02:09 PM   #1
Professional Chef
 
leeor_net's Avatar
 
Join Date: Apr 2004
Location: Charles Town, WV
Posts: 144
[solved] Base Class Overloaded Virtual Function

Hello again.

I've been working with a somewhat complex class heirarchy and have run into a problem. More than likely it stems from not fully understanding how C++ derived classes inherit from base classes.

To keep things simple, I have the following three classes defined as such:

Code:
class Foo
{
    private:
        virtual void myFunc() { printf("Hello!"); }
        virtual void myFunc2() { printf("'ello!"); }
};

class Bar : public Foo
{
    private:
        void myFunc() { printf("Hello 2!"); }
        void myFunc2() { printf("'ello 2!"); }
};

class FooBar : public Bar
{
    private:
        void myFunc() { printf("Hello 3!"); }
        void myFunc2() { printf("'ello 3!"); }
};
The weird thing that's happening is that when I call the overloaded function from FooBar myFunc() from a list of Foo's (e.g., std::vector<Foo*>), the correct function is called. But myFunc2() calls the function from Foo, not from Bar or FooBar.

I'm not sure this is clear enough but I'm hoping I provided enough information and that my problem is something really simple or that I just overlooked something.

Thanks!
__________________
- Leeor

Last edited by leeor_net; 07-12-2009 at 03:38 PM. Reason: Problem solved.
leeor_net is offline   Reply With Quote
Old 07-12-2009, 02:15 PM   #2
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 16,078
I see no problem with this except for a few minor things:
- It's clearer if you add virtual to every function that is virtual. Every function that overrides a virtual function is a base class is considered a virtual function, but it isn't obvious right away unless you can see the base class.
- Don't use printf, use cout.

Aside from that, could you provide the smallest simplest code that demonstrates the problem?
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2010 Ultimate, C++0x
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
"Thanks for all your help. It's obvious yall really know what you're talking about when it comes to OOP/C++ stuff."
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.

Last edited by Elysia; 07-12-2009 at 02:39 PM.
Elysia is offline   Reply With Quote
Old 07-12-2009, 02:19 PM   #3
&TH of undefined behavior
 
Fordy's Avatar
 
Join Date: Aug 2001
Posts: 5,261
They are all private, how are they getting called?

>>Don't use print, use cout.

printf is still valid. Please dont bother giving a lecture about type safety.
__________________
"If A is success in life, then A equals x plus y plus z. Work is x; y is play; and z is keeping your mouth shut."
Albert Einstein (1879 - 1955)


Board Rules
Fordy is offline   Reply With Quote
Old 07-12-2009, 02:20 PM   #4
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 10,163
According to my compiler, neither MyFunc nor MyFunc2 are overloaded; code such as
Code:
    FooBar object;
    Foo* ptr = &object;
    object.myFunc2();
    ptr->myFunc2();
    object.myFunc();
    ptr->myFunc();
does not of course work, since all the functions are private, but the first ones both resolve to FooBar::myFunc[2] and the second ones both resolve to Foo::myFunc[2], not FooBar. (Edit: by "first ones" I mean object., and by "second ones" I mean ptr->.)
tabstop is offline   Reply With Quote
Old 07-12-2009, 02:36 PM   #5
Professional Chef
 
leeor_net's Avatar
 
Join Date: Apr 2004
Location: Charles Town, WV
Posts: 144
Quote:
Don't use print, use cout.
Yes, I know that. This was a quick and dirty example to illustrate a point.

The code that I'm having trouble with is big and complex. But I'll strip out the stuff that isn't necessary. Here goes:

Code:
class Control
{
public:
	Control();
	void update();

	addControl(Control *);
	update();
private:
	virtual void draw();
	virtual void initialize();
};


class Window : public Control
{
public:
	Window();
	~Window();

private:
	void draw();
	void initialize();

	std::string	mTitlebar;
	int		mTitlebarHeight;
};


class DebugWindow : public Window
{
public:
    DebugWindow();
    ~DebugWindow();

private:
	void initialize();
};

In particular the trouble shows up when I run the addControl() function:

Code:
void Control::addControl(Control *control)
{
	mChildControls.push_back(control);
	mChildControls.back()->initialize();
}
mChildControls.back()->initialize() only ever gets called once and only runs the initialize() function from the class Control, not Window or DebugWindow.

The update function looks like this:

Code:
void Control::update()
{
	draw();

	for(unsigned int i = 0; i < mChildControls.size(); i++)
		mChildControls[i]->update();
}
This function tells the Control to draw itself and then to iterate through all of its children and tells them to update themselves which in turn calls their update and so on... Now, this works. The correct draw() function is called.

I may have just answered my own question as to why so now the question has turned into how. But just in case, I'm still asking...

mChildControls is defined as a vector<Control*>. There are probably a few things here and there that don't appear to be defined but just note that I've stripped out all of the irrelevant functions/variables/etc.
__________________
- Leeor

Last edited by leeor_net; 07-12-2009 at 02:52 PM.
leeor_net is offline   Reply With Quote
Old 07-12-2009, 02:41 PM   #6
Mysterious C++ User
 
Elysia's Avatar
 
Join Date: Oct 2007
Posts: 16,078
Quote:
Originally Posted by Fordy View Post
>>Don't use print, use cout.
printf is still valid. Please dont bother giving a lecture about type safety.
But should be avoided in C++, unless you have a very good reason.
Sure, go ahead and use printf and other C-family functions, but chances are it will become "C+" code instead of C++ code then.

Oh and consider that private functions aren't inherited, so it may just be that the functions are hidden instead of overloaded. It didn't occur to me before. Perhaps you want to use protected?
I am also going to have to rant a little about not removing parameter names.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2010 Ultimate, C++0x
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
"Thanks for all your help. It's obvious yall really know what you're talking about when it comes to OOP/C++ stuff."
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.

Last edited by Elysia; 07-12-2009 at 02:44 PM.
Elysia is offline   Reply With Quote
Old 07-12-2009, 02:45 PM   #7
Professional Chef
 
leeor_net's Avatar
 
Join Date: Apr 2004
Location: Charles Town, WV
Posts: 144
I;m not one to complain but can we keep the irrelevant chatter out of this topic? This isn't a debate about coding style, appropriateness of function calls, etc.

I tried moving around the functions to protected and public but no game. Clearly I've misunderstood something.

Thank you.
__________________
- Leeor

Last edited by leeor_net; 07-12-2009 at 02:50 PM.
leeor_net is offline   Reply With Quote
Old 07-12-2009, 02:55 PM   #8
and the Hat of Guessing
 
tabstop's Avatar
 
Join Date: Nov 2007
Posts: 10,163
I'm not sure I've got the hang of what your problem is. I've modified your code so that it makes sense and whatever:
Code:
#include <cstdio>
#include <string>
#include <vector>

class Control
{
public:
	void update();

	void addControl(Control *);
private:
    std::vector<Control *> mChildControls;
	virtual void draw();
	virtual void initialize();
};

void Control::draw() {
    printf("Control::draw\n");
}

void Control::initialize() {
    printf("Control::initialize\n");
}

class Window : public Control
{
public:

private:
	void draw();
	void initialize();

	std::string	mTitlebar;
	int		mTitlebarHeight;
};

void Window::draw() {
    printf("Window::draw\n");
}

void Window::initialize() {
    printf("Window::initialize\n");
}


class DebugWindow : public Window
{
public:

private:
	void initialize();
};

void DebugWindow::initialize() {
    printf("DebugWindow::initialize\n");
}

void Control::addControl(Control *control)
{
	mChildControls.push_back(control);
	mChildControls.back()->initialize();
}

void Control::update()
{
	draw();

	for(unsigned int i = 0; i < mChildControls.size(); i++)
		mChildControls[i]->update();
}

int main() {
    Window foo;
    DebugWindow bar;
    Control bob;
    bob.addControl(&foo);
    bob.addControl(&bar);
    return 0;
}
This prints
Code:
Window::initialize
DebugWindow::initialize
as you probably want. Can you modify this to show what's going on?
tabstop is offline   Reply With Quote
Old 07-12-2009, 02:56 PM   #9
&TH of undefined behavior
 
Fordy's Avatar
 
Join Date: Aug 2001
Posts: 5,261
Quote:
Originally Posted by leeor_net View Post
I;m not one to complain but can we keep the irrelevant chatter out of this topic? This isn't a debate about coding style, appropriateness of function calls, etc.
I know mate. Some people think that by pointing out pointless things like that they are helping.

Not wanting to ask an obvious question, but when you pass a control to addControl, you are passing a Window or DebugWindow via a Control pointer and not just a plain old Control object are you?
__________________
"If A is success in life, then A equals x plus y plus z. Work is x; y is play; and z is keeping your mouth shut."
Albert Einstein (1879 - 1955)


Board Rules
Fordy is offline   Reply With Quote
Old 07-12-2009, 03:13 PM   #10
Professional Chef
 
leeor_net's Avatar
 
Join Date: Apr 2004
Location: Charles Town, WV
Posts: 144
Nope, was definitely passing in a DebugWindow object.

Now here's the funny thing. I figured out my problem and I really could slap myself.

The way I have everything set up, I have what I call a Top Level or Root control. When I created DebugWindow, I... forgot to call addControl() to the root... <sigh>. It never occured to me that that could be the problem.

I hope I haven't wasted anybody's time. I do appreciate the comments and the suggestions... Thanks again!
__________________
- Leeor
leeor_net is offline   Reply With Quote
Old 07-12-2009, 08:16 PM   #11
and the hat of sweating
 
Join Date: Aug 2007
Location: Toronto, ON
Posts: 3,425
You aren't "overloading" any functions, you're "overriding" them. Overloading has nothing to do with inheritance.
__________________
"I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

"the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010
cpjust is offline   Reply With Quote
Old 07-13-2009, 06:37 AM   #12
Professional Chef
 
leeor_net's Avatar
 
Join Date: Apr 2004
Location: Charles Town, WV
Posts: 144
Yes, I realize that. Thank you for the vocabulary lesson...
__________________
- Leeor

Last edited by leeor_net; 07-13-2009 at 07:19 AM.
leeor_net is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Abnormal Program Termination when executed from C:\Program Files\... m37h0d Windows Programming 48 09-26-2008 03:45 AM
deriving classes l2u C++ Programming 12 01-15-2007 05:01 PM
Interface Question smog890 C Programming 11 06-03-2002 05:06 PM
qt help Unregistered Linux Programming 1 04-20-2002 09:51 AM
Exporting Object Hierarchies from a DLL andy668 C++ Programming 0 10-20-2001 01:26 PM


All times are GMT -6. The time now is 12:14 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22