Abstract classes

T

TBass

Hello. I'm trying to make an abstract class, but when I declare one of
the derived classes, I get the error "cannot instantiate abstract
class". Can anyone tell me what I'm doing wrong?

ABSTRACT CLASS:

class CDCtrl
{

protected:
CDCtrl(CDCtrl &c);

public:


CDCtrl( void );
virtual ~CDCtrl( void );


/* Control Unique ID */
unsigned int UID;

/* LOCATION ON THE PALLATE */
double X;
double Y;
double CX;
double CY;

/* APPEARANCE */
unsigned int ForeColor;
unsigned int BackColor;
bool Visible;

void Opacity(double Opacity);
double Opacity(void);



virtual bool InRect(double x, double y) const = 0;
virtual bool OnLButtonDown(double x, double y) = 0;
virtual bool OnLButtonUp(double x, double y) = 0;
virtual bool OnRButtonDown(double x, double y) = 0;
virtual bool OnRButtonUp(double x, double y) = 0;

virtual bool OnMouseMove(double x, double y, bool button_flag)
= 0;

virtual bool OnKeyDown( unsigned int VKeyCode, unsigned int ModKeys )
= 0;

virtual void Draw( DPalette &refPalette );




protected:
double m_opacity;

}; /* Class CDCtrl */


/*
* DCtrl.c
* The Daedalus control base classes and templates.
*/

#include ".\DCtrl.h"

/*
* CONSTRUCTOR
*/
CDCtrl::CDCtrl( void ) :
X(0),
Y(0),
CX(0),
CY(0),
UID(0),
ForeColor(0x000000),
BackColor(0xFFFFFF),
Visible(true),
m_opacity(1)
{
} /* CDCtrl::CDCtrl */



/*
* DESTRUCTOR
*/
CDCtrl::~CDCtrl( void )
{
} /* CDCtrl::CDCtrl */



/*
* CDCtrl::Opacity
*/
void
CDCtrl::Opacity( double Opacity )
{
if ( Opacity < 0 )
{
m_opacity = 0;
}
else if ( Opacity > 1 )
{
m_opacity = 1;
}
else
{
m_opacity = Opacity;
}
} /* CDCtrl::Opacity */


/*
* CDCtrl::Opacity
*/
double
CDCtrl::Opacity(void)
{
return m_opacity;
}


DERIVED CLASS:

class CDCtrl_Button : public CDCtrl
{
public:

CDCtrl_Button(void);
~CDCtrl_Button(void);

int Value() const { return m_value & 0x01; }
void Value(int value);

/*
virtual bool InRect(double x, double y);
virtual bool OnLButtonDown(double x, double y);
virtual bool OnLButtonUp(double x, double y);
virtual bool OnRButtonDown(double x, double y);
virtual bool OnRButtonUp(double x, double y);

virtual bool OnMouseMove(double x, double y, bool
button_flag);

virtual bool OnKeyDown( unsigned int VKeyCode, unsigned int
ModKeys );
*/

virtual void Draw( DPalette &refPalette );

private:

int m_value;
bool m_mouse_move;


};

/*
* CONSTRUCTOR
*/
CDCtrl_Button::CDCtrl_Button(void) :
CDCtrl(),
m_value(0),
m_mouse_move(0)
{
}



/*
* DESTRUCTOR
*/
CDCtrl_Button::~CDCtrl_Button(void)
{
}

/*
* CDCtrl_Button::draw
* Render the control on to the pallete.
*/
void
CDCtrl_Button::Draw( DPalette &refPalette )
{

refPalette.roundedRect( X, Y, CX, CY, 2, 2, 2, 2 );

}


FROM THE MAIN PROGRAM:

CDCtrl_Button m_button;


This is my first abstract class. Can anyone tell me what I'm doing
wrong?

Thanks in advance,
TBJ
 
B

Brian Szmyd

Where are:

virtual bool InRect(double x, double y); virtual bool
OnLButtonDown(double x, double y); virtual bool
OnLButtonUp(double x, double y); virtual bool
OnRButtonDown(double x, double y); virtual bool
OnRButtonUp(double x, double y);

Implemented? You've made them pure virtual in your parent class, but I
don't see the child class implementation of them. You can't instantiate
an object of a class that has any pure virtual methods (inherited or not).
 
T

TBass

Where are:

virtual bool InRect(double x, double y); virtual bool
OnLButtonDown(double x, double y); virtual bool
OnLButtonUp(double x, double y); virtual bool
OnRButtonDown(double x, double y); virtual bool
OnRButtonUp(double x, double y);

Implemented? You've made them pure virtual in your parent class, but I
don't see the child class implementation of them. You can't instantiate
an object of a class that has any pure virtual methods (inherited or not).

Ah! I thought I could pick and choose which virtual functions I wanted
to implement.

Thanks!
TBJ
 
R

robin

looks like you didn't provide implementation for the pure virtual
functions "OnMouseMove" and "OnKeyDown", which make the derived class
still an abstract class, which of course cannot be instantiated.
 
V

Victor Bazarov

TBass said:
Ah! I thought I could pick and choose which virtual functions I wanted
to implement.

You can. The problem is that your class cannot control which functions
of it are going to be called. And calling a pure virtual function (if
you don't implement it, it stays pure, right?) has undefined behaivour.

If you want to be able to have an object that does nothing upos one of
those actions, don't make those functions pure. Provide the compiler
with an implementation in the base class, and let it return 'false' (or
whatever makes sense for "default behaviour -- nothing is done"). Then
you can pick which behaviour change from the default to custom.

V
 
J

Joe Greer

Ah! I thought I could pick and choose which virtual functions I wanted
to implement.

Thanks!
TBJ

No... Any method declared in a class must be implemented somewhere.
The 'where' is what changes between pure virtuals, virtuals, and non-
virtuals. With pure virtuals, the method is guaranteed to be
implemented in a derived class. With virtuals, an implementation must
be available in the base class, but it can be overridden in the derived
classes. And, finally with non-virtuals, the implementation must be in
the base class and can't be overridden by a child. (Note, it can be
hidden be a new implementation in the child, but it is a bad idea.)

The class declaration is your contract with your user as to what
services your object provides. Rarely is faulting out an acceptible
response to an attempt to use a service.

joe
 
T

TBass

[snip]
No... Any method declared in a class must be implemented somewhere.
The 'where' is what changes between pure virtuals, virtuals, and non-
virtuals. With pure virtuals, the method is guaranteed to be
implemented in a derived class. With virtuals, an implementation must
be available in the base class, but it can be overridden in the derived
classes. And, finally with non-virtuals, the implementation must be in
the base class and can't be overridden by a child. (Note, it can be
hidden be a new implementation in the child, but it is a bad idea.)
[/snip]

That makes sense. I've got the code up and running now. Thanks
everyone!

Until my next stupid question... :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top