virtual functions/generic access

M

Mark Foley

I am implementing some functionality where there is a single
base class 'A' which provides some common functionality

There are then two classes derived from 'A', call them 'B' and 'C'.
Both 'B' and 'C' define functions specific only to their class. Somethng
like...


class A
{
void doX();
void doY();
}

class B : class A
{
void getInfo();
char * getBInfo();
}

class C : class A
{
void getInfo();
char * getCInfo();
}


I then have a list of objects. Some are based on 'B', some are based
on 'C', but I would like to treat them generically.

ob[0]->type.doX(); // always ok
ob[0]->type.getInfo(); // always ok
ob[0]->type.getCInfo(); // only ok if type is Class C

I know if I make getBInfo() virtual in the base class then I can
make the above call regardless. But then I have to provide some
return value for it in class A.

If I make it a pure virtual, then I need to provide an implementation
for it in the derived class.

Is there a way to treat a list of objects like this generically without
having to know their
actual type?

It seems kludgey to have something like:

virtual char * getBInfo() {return NULL};

in my base class, but perhaps that's the way it's done.

Thanks
Mark
 
V

Victor Bazarov

Mark said:
I am implementing some functionality where there is a single
base class 'A' which provides some common functionality

There are then two classes derived from 'A', call them 'B' and 'C'.
Both 'B' and 'C' define functions specific only to their class.
Somethng like...


class A
{
Probably

public:
void doX();
void doY();
} ;

class B : class A

You mean

class B : public A

Most likely

public:
void getInfo();
char * getBInfo();
} ;

class C : class A

You mean

class C : public A
{
void getInfo();
char * getCInfo();
}
;
I then have a list of objects. Some are based on 'B', some are based
on 'C', but I would like to treat them generically.

ob[0]->type.doX(); // always ok
ob[0]->type.getInfo(); // always ok
ob[0]->type.getCInfo(); // only ok if type is Class C

Are you claiming that that's what happens or setting forth requirements?
I know if I make getBInfo() virtual in the base class then I can
make the above call regardless.

Regardless of what? Which of the above calls is 'getBInfo()'?
But then I have to provide some
return value for it in class A.

If you intend to make it virtual and have it in 'A', you need to give
it the _covariant_ return value type. It can't just be "some".
If I make it a pure virtual, then I need to provide an implementation
for it in the derived class.

Only if you intend to instantiate the derived class.
Is there a way to treat a list of objects like this generically
without having to know their
actual type?

The only way to do that is to give them polymorphic behaviour (through
virtual functions, as you already mentioned).
It seems kludgey to have something like:

virtual char * getBInfo() {return NULL};

in my base class, but perhaps that's the way it's done.

It's _a_ way to do it. Whether it's the best way, is debatable.

V
 
M

Maarten Kronenburg

"Mark Foley" wrote in message
I am implementing some functionality where there is a single
base class 'A' which provides some common functionality

There are then two classes derived from 'A', call them 'B' and 'C'.
Both 'B' and 'C' define functions specific only to their class. Somethng
like...


class A
{
void doX();
void doY();
}

class B : class A
{
void getInfo();
char * getBInfo();
}

class C : class A
{
void getInfo();
char * getCInfo();
}


I then have a list of objects. Some are based on 'B', some are based
on 'C', but I would like to treat them generically.

ob[0]->type.doX(); // always ok
ob[0]->type.getInfo(); // always ok
ob[0]->type.getCInfo(); // only ok if type is Class C

I know if I make getBInfo() virtual in the base class then I can
make the above call regardless. But then I have to provide some
return value for it in class A.

If I make it a pure virtual, then I need to provide an implementation
for it in the derived class.

Is there a way to treat a list of objects like this generically without
having to know their
actual type?

It seems kludgey to have something like:

virtual char * getBInfo() {return NULL};

in my base class, but perhaps that's the way it's done.

Thanks
Mark

Mark,
Yes when you override a virtual function it must be declared as virtual in
the base class.
You can read more about virtual functions in
The C++ Programming Language, 3rd. ed., par. 12.2.6
and also on:
http://www.parashift.com/c++-faq-lite/virtual-functions.html
Regards, Maarten.
 
J

Jim Langston

Mark Foley said:
I am implementing some functionality where there is a single
base class 'A' which provides some common functionality

There are then two classes derived from 'A', call them 'B' and 'C'.
Both 'B' and 'C' define functions specific only to their class. Somethng
like...


class A
{
void doX();
void doY();
}

class B : class A
{
void getInfo();
char * getBInfo();
}

class C : class A
{
void getInfo();
char * getCInfo();
}


I then have a list of objects. Some are based on 'B', some are based
on 'C', but I would like to treat them generically.

ob[0]->type.doX(); // always ok
ob[0]->type.getInfo(); // always ok
ob[0]->type.getCInfo(); // only ok if type is Class C

I know if I make getBInfo() virtual in the base class then I can
make the above call regardless. But then I have to provide some
return value for it in class A.

If I make it a pure virtual, then I need to provide an implementation
for it in the derived class.

Is there a way to treat a list of objects like this generically without
having to know their
actual type?

It seems kludgey to have something like:

virtual char * getBInfo() {return NULL};

in my base class, but perhaps that's the way it's done.

Using polymorphism you can ask the instance if it is type C.

if ( dynamic_cast<C*>( ob[0] ) != NULL )
dynamic_cast<C*>( ob[0] )->getCInfo(); // only ok if type is Class
C
 
A

Alf P. Steinbach

* Mark Foley:
I am implementing some functionality where there is a single
base class 'A' which provides some common functionality

There are then two classes derived from 'A', call them 'B' and 'C'.
Both 'B' and 'C' define functions specific only to their class. Somethng
like...


class A
{
void doX();
void doY();
}

class B : class A
{
void getInfo();
char * getBInfo();
}

class C : class A
{
void getInfo();
char * getCInfo();
}


I then have a list of objects. Some are based on 'B', some are based
on 'C', but I would like to treat them generically.

ob[0]->type.doX(); // always ok
ob[0]->type.getInfo(); // always ok
ob[0]->type.getCInfo(); // only ok if type is Class C

I know if I make getBInfo() virtual in the base class then I can
make the above call regardless. But then I have to provide some
return value for it in class A.

If I make it a pure virtual, then I need to provide an implementation
for it in the derived class.

Is there a way to treat a list of objects like this generically without
having to know their actual type?

Yes.

First, you should move the common functionality getInfo() up to A, as a
virtual function.

For functions getBInfo() and getCInfo() you can simply invert the usage
pattern: instead of client code calling these functions on an object o,
you let the o object call back to the client code with the necessary
data. I.e., in class A you provide a function

virtual void callbackOn( CallbackInterface& someObject ) = 0;

and in class B e.g.

virtual void callbackOn( CallbackInterface& someObject )
{
someObject.doStuffWith( getBInfo() );
}

although you should probably reconsider the use of raw pointers, and
also the naming convention (get rid of "get" and "info"...).

Ditto for class C.

This is known as the visitor pattern (google).

It seems kludgey to have something like:

virtual char * getBInfo() {return NULL};

in my base class, but perhaps that's the way it's done.

It's kludgy and not the way it's done.

Hth.,

- Alf
 

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,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top