Classes and interfaces

W

Webster

Hello,

I want to create a Shape class and some subclasses such as Rectangle, Circle
etc. However for the Shape Class, I want to have a list of points (using a
vector) and also I want it so that the Shape Classes forces the subclasses
to implement a Draw() function. I believe what I want is called an
interface right?? If so, how do I go about creating the Shape Class to force
the subclasses to implement the Draw() function??

Thanks for any help!
 
V

Victor Bazarov

Webster said:
I want to create a Shape class and some subclasses such as Rectangle, Circle
etc. However for the Shape Class, I want to have a list of points (using a
vector) and also I want it so that the Shape Classes forces the subclasses
to implement a Draw() function. I believe what I want is called an
interface right??

Interface is a mechanism for communication between two parties. Any
function is an interface between the caller and the called (if those are
objects). So, yes, member functions fall into the "interface" category.
Whether it's something the base class _forces_ the derived classes to
implement or not does not matter.
If so, how do I go about creating the Shape Class to force
the subclasses to implement the Draw() function??

It has to be pure virtual.

V
 
J

Jeff Schwab

Webster said:
Hello,

I want to create a Shape class and some subclasses such as Rectangle, Circle
etc. However for the Shape Class, I want to have a list of points (using a
vector) and also I want it so that the Shape Classes forces the subclasses
to implement a Draw() function. I believe what I want is called an
interface right??

In Java. In C++, it's called an "abstract class."
If so, how do I go about creating the Shape Class to force
the subclasses to implement the Draw() function??

struct Shape
{
virtual void draw( ) =0;
};
 
J

Jumbo

Webster said:
Hello,

I want to create a Shape class and some subclasses such as Rectangle, Circle
etc. However for the Shape Class, I want to have a list of points (using a
vector) and also I want it so that the Shape Classes forces the subclasses
to implement a Draw() function. I believe what I want is called an
interface right?? If so, how do I go about creating the Shape Class to force
the subclasses to implement the Draw() function??

Thanks for any help!
An abstract or pure virtual base class is the same thing AFAIK, and what
this means is a class that cannot be instantiated i.e: it is designed in
such a way that is is only meant to be derived from. These are called
Interfaces in COM, C# etc (dunno about Java).
Note: classes of this type are also know as ADT's ( Abstract data types).

However what you seem to require is a virtual method, which is normally
closely related with ADT's ( Abstract data types) as an ADT which exposes
any methods will normall use vitual methods.
What virtual means is tell the compiler that I intend to overide this
function in a derived class i.e:
class Class1{
public:
virtual void Draw(){std::cout << "Class1 draw()"<< std::endl;}
};

That is an example of a virtual method.
Next if you create a derived class an incorporate a method with the same
signature like so:

class Class2:public Class1{
public:
void Draw(){std::cout << "Class2 draw()"<< std::endl;}
};


When you create an instance of the derived class the compiler knows to call
the correct method i.e:
int main(){
Class1 obj1;
Class2 obj2;
obj1.Draw(); //outputs Class1 Draw()
obj2.Draw(); //outputs Class2 Draw()

return 0;
}

If a function is virtual then it will percolate up to a derived class if the
derived class contains a method of the same signature.
I'm not sure if I have explained this very well but I hope it helps.

You can also create instances of the base class, you don't need to make it
an ADT.
Additionally if you do want to make a base class an ADT then you put '=0'
after one of the methods. The following code would make Class1 pure virtual
and therefore you would be intending that it is not directly initialised and
only to be used as an interface. (This is what lies at the heart of COM and
ATL(Abstract template library) ):

class Class1{
public:
virtual void Draw() =0 {std::cout << "Class1 draw()"<< std::endl;}
};

You cannot create an instance of Class1 now but Class2 can still derive from
it and the virtual functions will still percolate up to Class2. Be sure to
include virtual destructors etc.

However having said that you can declare a pointer to an ADT. It all gets a
bit complicated from here so I'll leave it at that.
 
D

Daniel T.

Webster said:
I want to create a Shape class and some subclasses such as Rectangle, Circle
etc. However for the Shape Class, I want to have a list of points (using a
vector) and also I want it so that the Shape Classes forces the subclasses
to implement a Draw() function. I believe what I want is called an
interface right?? If so, how do I go about creating the Shape Class to force
the subclasses to implement the Draw() function??

Thanks for any help!

class Shape {
public:
virtual ~Shape() { }
virtual std::vector<point> getPoints() const = 0;
virtual void draw() = 0;
};

I have to ask, what are shapes supposed to draw on? Shouldn't that be a
parameter of the draw member-function?
 
W

Webster

Daniel T. said:
class Shape {
public:
virtual ~Shape() { }
virtual std::vector<point> getPoints() const = 0;
virtual void draw() = 0;
};

Cool.. thanks for the exact class!!
I have to ask, what are shapes supposed to draw on? Shouldn't that be a
parameter of the draw member-function?

The draw function will be called from another class. I am using FLTK and
OpenGL so there is a panel that calls the Draw() function which just sends
the points.
 
C

Cy Edmunds

Webster said:
Cool.. thanks for the exact class!!


The draw function will be called from another class. I am using FLTK and
OpenGL so there is a panel that calls the Draw() function which just sends
the points.

Well then let me suggest an alternative: use a standalone function to draw
the points:

class Shape {
// same as before except no draw() function
};

void draw(const Shape &);

You are considering a shape to be a bunch of points. Fair enough, but what
does that have to do with drawing? Absolutely nothing. Your Shape family of
classes might prove useful in other applications if you don't package the
drawing stuff with them.
 
W

Webster

Well then let me suggest an alternative: use a standalone function to draw
the points:

class Shape {
// same as before except no draw() function
};

void draw(const Shape &);

You are considering a shape to be a bunch of points. Fair enough, but what
does that have to do with drawing? Absolutely nothing. Your Shape family of
classes might prove useful in other applications if you don't package the
drawing stuff with them.

You bring up a very good and valid point... but how can I draw the shape
unless I know what to do with the points?? For instance, if I have a Line
specified by 2 Points, I just draw a line between them, but a Rectangle
specified by two Points, I have to derive the extra 2 Points. That is why I
wanted a Draw() function for each Shape, so that I can know how to draw
them, or if any special considerations need to be taken into account.
 
J

Jeff Schwab

Webster said:
You bring up a very good and valid point... but how can I draw the shape
unless I know what to do with the points?? For instance, if I have a Line
specified by 2 Points, I just draw a line between them, but a Rectangle
specified by two Points, I have to derive the extra 2 Points. That is why I
wanted a Draw() function for each Shape, so that I can know how to draw
them, or if any special considerations need to be taken into account.

If you're writing a very small program, putting the shapes in a
hierarchy with a "draw" method is probably okay. For larger projects,
it may be worth creating a separate "Drawer" hierarchy, and moving the
polymorphism of Shapes to compile-time.


#include <iostream>

namespace Shapes
{
struct Rectangle { };
struct Triangle { };
}

namespace Drawing
{
template< typename T >
void draw( T const& t )
{
std::cout << "Don't know how to draw typeid \""
<< typeid( t ).name( ) << "\". :(\n";
}

template< >
void draw( Shapes::Rectangle const& rectangle )
{
std::cout << "I drew a rectangle.\n";
}

template< >
void draw( Shapes::Triangle const& triangle )
{
std::cout << "I drew a triangle.\n";
}

struct Abstract_drawer
{
virtual void draw_shape( ) =0;
};

template< typename Shape >
struct Drawer: Abstract_drawer
{
void draw_shape( )
{
draw( shape );
}

Shape shape;
};
}

#include <algorithm>
#include <vector>

int main( )
{
using namespace Shapes;
using namespace Drawing;

Drawer< Rectangle > rectangle_drawer;
Drawer< Triangle > triangle_drawer;
Drawer< int > int_drawer;

std::vector< Abstract_drawer* > drawers;

drawers.push_back( &rectangle_drawer );
drawers.push_back( &triangle_drawer );
drawers.push_back( &int_drawer );

std::for_each( drawers.begin( ),
drawers.end( ),
std::mem_fun( &Abstract_drawer::draw_shape ) );
}
 
F

Frank Puck

struct Shape
{
virtual void draw( ) =0;
};


make this

virtual void draw() const = 0;

as by drawing itself the object should not change.
Usually you also have a device/window/printer to draw on,
which needs to be passed to the method.

virtual void draw(DEVICE *) const = 0;

In windows this would be a HDC (called differently on other systems).
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top