C++ inheritance question

yea, I know this isn’t a C++ question group, but I figure there are
enough
really smart people here to know the answer fast.

I’m working on a GUI library for one of my many project, and for this
I’ve
created an absolute base class called CWidget.

class CWidget
{
public:
Uint16 x;
Uint16 y;
Uint16 w;
Uint16 h;
Uint8 status;
CWidget *parent;
Uint8 *bitmap; // several controls will be able to have bitmaps to
display
// function Pointer must be filled in for the widget to work
int (*whatIDo)(void);
virtual int runMe(void) = 0;
virtual int drawMe(void) = 0;
virtual bool setMyStatus(Uint8 newStatus) = 0;
virtual bool amIClickedOn(Uint16 mousex, Uint16 mousey) = 0;
virtual void relativeTo(CWidget *newParent)
{
parent = newParent;
}
};

One of the derived classes is CWidgetContainer
class CWidgetContainer : public CWidget
{
private:
struct WidgetList *node;
struct WidgetList *itterator;
public:
CWidgetContainer();
~CWidgetContainer();
int insertWidget(CWidget *item);
int resetWidgetItterator();
CWidget *getWidget();
int next();
void previous();
int runMe(void);
int drawMe(void);
bool setMyStatus(Uint8 newStatus) { return false; }
bool amIClickedOn(Uint16 mousex, Uint16 mousey) { return false; }
};

When this compiles everything works fine, but I get the following
warning:
warning ‘class CWidgetContainer’ has virtual functions but non-virtual
destructor

Now I’m wondering why? Is it because CWidgetContainer has a destructor
and the
class is derived from CWidget which has virtual functions? As I said it
works,
I just want to clean up output from the compile.

Oh yea I’m building with egcs 2.91.66 on RedHat 6.1 (and KDevelop if
that matters)

on another note…
CWidget
CWidgetContainer
CWidgetRun
RunWidgetRun
sorry…

		-fjr-- 

Frank J. Ramsay
@Frank_Ramsay

In the base class CWidget, declare a virtual destructor and possible a
constructor.
I’m still learning C++ also but am fairly sure about the virtual destructor.> ----- Original Message -----

From: owner-sdl@lokigames.com [mailto:owner-sdl at lokigames.com]On Behalf
Of Frank Ramsay
Sent: Tuesday, March 28, 2000 4:50 PM
To: sdl at lokigames.com
Subject: [SDL] C++ inheritance question

yea, I know this isn’t a C++ question group, but I figure there are
enough
really smart people here to know the answer fast.

I’m working on a GUI library for one of my many project, and for this
I’ve
created an absolute base class called CWidget.

class CWidget
{
public:
Uint16 x;
Uint16 y;
Uint16 w;
Uint16 h;
Uint8 status;
CWidget *parent;
Uint8 *bitmap; // several controls will be able to have bitmaps to
display
// function Pointer must be filled in for the widget to work
int (*whatIDo)(void);
virtual int runMe(void) = 0;
virtual int drawMe(void) = 0;
virtual bool setMyStatus(Uint8 newStatus) = 0;
virtual bool amIClickedOn(Uint16 mousex, Uint16 mousey) = 0;
virtual void relativeTo(CWidget *newParent)
{
parent = newParent;
}
};

One of the derived classes is CWidgetContainer
class CWidgetContainer : public CWidget
{
private:
struct WidgetList *node;
struct WidgetList *itterator;
public:
CWidgetContainer();
~CWidgetContainer();
int insertWidget(CWidget *item);
int resetWidgetItterator();
CWidget *getWidget();
int next();
void previous();
int runMe(void);
int drawMe(void);
bool setMyStatus(Uint8 newStatus) { return false; }
bool amIClickedOn(Uint16 mousex, Uint16 mousey) { return false; }
};

When this compiles everything works fine, but I get the following
warning:
warning ‘class CWidgetContainer’ has virtual functions but non-virtual
destructor

Now I’m wondering why? Is it because CWidgetContainer has a destructor
and the
class is derived from CWidget which has virtual functions? As I said it
works,
I just want to clean up output from the compile.

Oh yea I’m building with egcs 2.91.66 on RedHat 6.1 (and KDevelop if
that matters)

on another note…
CWidget
CWidgetContainer
CWidgetRun
RunWidgetRun
sorry…

  	-fjr


Frank J. Ramsay
fjr at marsdome.penguinpowered.com

hi`

I don’t understand the warning and couldn’t find a trace in the C++
standard why your code shouldn’t work - in fact the below code compiles
and runs flawlessly with egcs 2.91.66 here. Maybe I overlooked something
but the below code should resemble your code.

class A
{
public:
virtual void func()=0;
};
class B : public A
{
public:
B() {};
~B() {};
void func() {};
};
int main()
{
B b;
return 0;
}

Frank Ramsay wrote:>

When this compiles everything works fine, but I get the following
warning:
warning ‘class CWidgetContainer’ has virtual functions but non-virtual


Daniel Vogel My opinions may have changed,
666 @ http://grafzahl.de but not the fact that I am right

Frank Ramsay wrote:

yea, I know this isn’t a C++ question group, but I figure there are
enough
really smart people here to know the answer fast.

I’m working on a GUI library for one of my many project, and for this
I’ve
created an absolute base class called CWidget.

class CWidget
{
public:
Uint16 x;
Uint16 y;
Uint16 w;
Uint16 h;
Uint8 status;
CWidget *parent;
Uint8 *bitmap; // several controls will be able to have bitmaps to
display
// function Pointer must be filled in for the widget to work
int (*whatIDo)(void);
virtual int runMe(void) = 0;
virtual int drawMe(void) = 0;
virtual bool setMyStatus(Uint8 newStatus) = 0;
virtual bool amIClickedOn(Uint16 mousex, Uint16 mousey) = 0;
virtual void relativeTo(CWidget *newParent)
{
parent = newParent;
}
};

One of the derived classes is CWidgetContainer
class CWidgetContainer : public CWidget
{
private:
struct WidgetList *node;
struct WidgetList *itterator;
public:
CWidgetContainer();
~CWidgetContainer();
int insertWidget(CWidget *item);
int resetWidgetItterator();
CWidget *getWidget();
int next();
void previous();
int runMe(void);
int drawMe(void);
bool setMyStatus(Uint8 newStatus) { return false; }
bool amIClickedOn(Uint16 mousex, Uint16 mousey) { return false; }
};

When this compiles everything works fine, but I get the following
warning:
warning ‘class CWidgetContainer’ has virtual functions but non-virtual
destructor

A class with virtual member functions should have a virtual destructor.
So declare and implement one in the base class.

Otherwise, if you delete a derived object through a base class pointer,
the result is undefined, because the call will be static, not dynamic
(as you want for polymorphism).–
Marc A. Lepage
Software Developer
Molecular Mining Corporation
http://www.molecularmining.com/

In the base class CWidget, declare a virtual destructor and possible a
constructor. I’m still learning C++ also but am fairly sure about the
virtual destructor.

The reason you need a virtual destructor on any class that has virtual
methods is because you can do something like…

class one {
	public:
		virtual ~one() {
			cout << "one" << endl;
		}
		virtual void something() const {
			cout << "something" << endl;
		}
};
class two : public one {
	public:
		virtual ~two() {
			cout << "two" << endl;
		}
		virtual void something() const {
			cout << "nothing" << endl;
		}
};
int main() {
	one* base_class_pointer = new two;
	base_class_pointer->something();
	delete base_class_pointer;
}

When you use a base class pointer to delete the instance, it will call the
derived class’ virtual destructor to free any resources it may be
respinsible for. Try the above without virtual destructors (ignoring
the compiler warnings) and you will see that only the base class
destructor is called.

Any polymorphic class needs to have virtual destructors because the class
can be used with a base class reference/pointer.

Paul Braman
@Paul_BramanOn Tue, 28 Mar 2000, Prasanth Kumar wrote:

I also don’t understand the point in using a class over a struct when you
have everything in public:.

Structs and classes are identical except classes default to private and
structs default to public. Both can have member functions…

Dave

Paul Braman wrote:

Any polymorphic class needs to have virtual destructors because the class
can be used with a base class reference/pointer.

The advanced rule is: “only if you are going to delete it through a base
class pointer.”

There are situations (e.g., templates and the Singleton design pattern)
where you can be sure this will never happen, and it doesn’t matter.

The beginner’s rule is: “Make sure base classes have virtual
destructors.” [Meyers Item 14]–
Marc A. Lepage
Software Developer
Molecular Mining Corporation
http://www.molecularmining.com/

Hi there,
I started hacking on an SDL audio application again. Eventually, I
ran into the same wall as earlier, where SDL could no longer create the
audio thread. The only remedy to this the last time I saw it was to reboot
my Linux system. This time, I decided to try some of the SDL demo apps. I
ran the torturethread.c program a few times and now my machine is in a
state where it can’t run anything SDL. The programs either complain that
they can’t create a semaphore or that they’re just plain out of memory.
What’s going on? What am I doing wrong? What do I need to avoid doing? The
reason I ask if SDL is in its own world is that the rest of the system
seems unaffected. E.g., there is plenty of memory available and the rest
of my applications have no trouble running.

Any ideas? Thanks...
    -The Mighty Mike Master
    http://tmmm.simplenet.com

Hi there,
I started hacking on an SDL audio application again. Eventually, I
ran into the same wall as earlier, where SDL could no longer create the
audio thread. The only remedy to this the last time I saw it was to reboot
my Linux system. This time, I decided to try some of the SDL demo apps. I
ran the torturethread.c program a few times and now my machine is in a
state where it can’t run anything SDL. The programs either complain that
they can’t create a semaphore or that they’re just plain out of memory.
What’s going on? What am I doing wrong? What do I need to avoid doing? The
reason I ask if SDL is in its own world is that the rest of the system
seems unaffected. E.g., there is plenty of memory available and the rest
of my applications have no trouble running.

Does your system use the pthread library?

-Sam Lantinga				(slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

The beginner’s rule is: “Make sure base classes have virtual
destructors.” [Meyers Item 14]

Well, we were answering a beginner’s question. :slight_smile: (Note, not a “beginner
question”. There’s a difference.)

Paul Braman
Authorized C++ Developer
@Paul_BramanOn Tue, 28 Mar 2000, Marc A. Lepage wrote:

Did you do a ps ax and kill all the sdl related stuff?On Tue, 28 Mar 2000, you wrote:

Hi there,
I started hacking on an SDL audio application again. Eventually, I
ran into the same wall as earlier, where SDL could no longer create the
audio thread. The only remedy to this the last time I saw it was to reboot
my Linux system. This time, I decided to try some of the SDL demo apps. I
ran the torturethread.c program a few times and now my machine is in a
state where it can’t run anything SDL. The programs either complain that
they can’t create a semaphore or that they’re just plain out of memory.
What’s going on? What am I doing wrong? What do I need to avoid doing? The
reason I ask if SDL is in its own world is that the rest of the system
seems unaffected. E.g., there is plenty of memory available and the rest
of my applications have no trouble running.

Any ideas? Thanks…
-The Mighty Mike Master
http://tmmm.simplenet.com

-Garrett, WPI student majoring in Computer Science
"The fastest way to succeed is to look as if you’re playing by somebody
else’s rules, while quietly playing by your own." -Michael Konda

Does your system use the pthread library?

The configure process finds pthreads and compiles with the

SDL_USE_PTHREADS directive. However, I see from the SDL_mutex.c code that
if glibc version == 2.0.x (which is true on my system), then SDL works
around threading bugs by using System V IPC.

I'm getting the "Couldn't create semaphore" error and the only

place that error message shows up in the
code is in the non-pthreads #ifdef in SDL_mutex.c. When it fails with that
semaphore error, it’s failing on a call to semget(). I separated that call
out to a little test program and identified the specific error as ENOSPC
which, according to the man page, means that the system has run out of
semaphores to allocate.

    -The Mighty Mike Master
    http://tmmm.simplenet.comOn Tue, 28 Mar 2000, Sam Lantinga wrote:

Did you do a ps ax and kill all the sdl related stuff?

Yep, everything related to SDL and the application I'm developing

is dead. Furthermore, the system still has plenty of resources, but SDL is
still throwing some strange errors.

    -The Mighty Mike Master
    http://tmmm.simplenet.comOn Tue, 28 Mar 2000, Garrett wrote:

I’m getting the “Couldn’t create semaphore” error and the only
place that error message shows up in the
code is in the non-pthreads #ifdef in SDL_mutex.c. When it fails with that
semaphore error, it’s failing on a call to semget(). I separated that call
out to a little test program and identified the specific error as ENOSPC
which, according to the man page, means that the system has run out of
semaphores to allocate.

Interesting. Apparently you are leaking semaphores when threads are not
being cleaned up properly. This is not entirely unexpected. Perhaps SDL
should keep track of the threads and semaphores and clean them all up when
the application quits?

I recommend that you upgrade to glibc-2.1, specifically because of those
threading problems SDL is trying to work around, though.

See ya!
-Sam Lantinga (slouken at devolution.com)

Lead Programmer, Loki Entertainment Software–
“Any sufficiently advanced bug is indistinguishable from a feature”
– Rich Kulawiec

The Mighty Mike Master wrote:

Hi there,
I started hacking on an SDL audio application again. Eventually, I
ran into the same wall as earlier, where SDL could no longer create the
audio thread.

At the command-line try typing ‘ipcs’. It will list all the shared
memory and semaphore arrays that you have. If it’s a long list, and
you’re not running anything else, you can remove them with ipcrm (do a
’man ipcrm’).

Structs do not have member functions, they CAN have functions that
operate on them but are not exclusive to them. While Classes CAN have
member functions that ARE exclusive to them .

— Dave wrote:> I also don’t understand the point in using a class over a struct when

you
have everything in public:.

Structs and classes are identical except classes default to private
and
structs default to public. Both can have member functions…

Dave

=====
Jason Platt.

“In theory: theory and practice are the same.
In practice: they arn’t.”

ICQ# 1546328


Do You Yahoo!?
Talk to your friends online with Yahoo! Messenger.

Jason Platt wrote:

Structs do not have member functions, they CAN have functions that
operate on them but are not exclusive to them. While Classes CAN have
member functions that ARE exclusive to them .

In C++, “struct” and “class” is ALMOST EXACTLY the same thing. The ONLY
difference is the default protection: “class” is “private” by default
and “struct” is “public” by default.

This:

class Foo {
void doFoo();
};

and this:

struct Foo {
private:
void doFoo();
};

is EXACTLY the same thing. Code that works with the first example with
work the same way with the second example.–
Pierre Phaneuf
Systems Exorcist

Jason Platt wrote:

Structs do not have member functions, they CAN have functions that
operate on them but are not exclusive to them. While Classes CAN have
member functions that ARE exclusive to them .

No. The only difference between a struct and a class is the default
access specifier.–
Marc A. Lepage
Software Developer
Molecular Mining Corporation
http://www.molecularmining.com/

“Marc A. Lepage” wrote:

No. The only difference between a struct and a class is the default
access specifier.

This goes even further. You can use a struct to access member variables
and member functions of a class in some cases (no virtual functions and
some other limitations).–
Daniel Vogel My opinions may have changed,
666 @ http://grafzahl.de but not the fact that I am right

the struct inside the CWidgetContainer class is this:

struct WidgetList
{
CWidget *aWidget;
struct WidgetList *next;
};

I implemented it as a struct because
1: I don’t like forward refrencing classes. I know there is nothing
wrong with it and it works fine. But I just don’t like the way it
looks. and with a struct I don’t have to.
2: using a class for this gives me nothing I could not get in a struct.

It probably would have been clearer if I called the struct WidgetNode
instead of WidgetList…

		-fjr

Dave wrote:>

I also don’t understand the point in using a class over a struct when you
have everything in public:.

Structs and classes are identical except classes default to private and
structs default to public. Both can have member functions…

Dave


Frank J. Ramsay
@Frank_Ramsay