Passing a class to a pure virtual function (without templates)

C

captaincurk

Hello there,

I have the following problem:

// abstract base class
class A {
public:
virtual void addItems() =0;
};

class B : public A {
public:
virtual void addItems() {
// here I need to instantiate objects of a given type
}
}

In B's something() function, I need to fill an internal list with
objects of a specific type. I need some way to pass my classname to
the function. Naturally I would try

template <class InstantiationClass> virtual void addItems() {
list.push_back(new InstantiationClass());
}

Unfortunately that does not work, because pure virtual template
functions obviously don't work. Now I could move the template up to
the class B, but that is not very useful, as in my main program I will
call addItems very often and with different classes as parameters. Is
there an easy way to do this?

One way I could think of is to make a global constructor for each
class I want to use and then pass a function reference, but that
creates a LOT of new functions, which are only called once. And also
since my code resides in a framework, the call to addItems should be
very easy and straightforward and work with custom classes.

Thanks in advance and cheers,
Jonas
 
D

DerTopper

Hello there,

I have the following problem:

// abstract base class
class A {
public:
virtual void addItems() =0;
};

class B : public A {
public:
virtual void addItems() {
// here I need to instantiate objects of a given type
}
}

In B's something() function, I need to fill an internal list with
objects of a specific type. I need some way to pass my classname to
the function. Naturally I would try

template <class InstantiationClass> virtual void addItems() {
list.push_back(new InstantiationClass());
}

Unfortunately that does not work, because pure virtual template
functions obviously don't work. Now I could move the template up to
the class B, but that is not very useful, as in my main program I will
call addItems very often and with different classes as parameters

Huh? What parameters? addItems doesn't take any parameters?
. Is
there an easy way to do this?

If you really need a virtual method for adding some Items, but also
have a lot of different things to create, you won't get a around class
template. Remember that you'll need a vtable to make virtual methods
work, and you only get a different vtable for each class you define.

Your problem description reads very confusing. The method for adding
new items takes no parameters, which is a bit odd. Probably that is
the source of your problem. Try to write a short summary of what
addItems should do, and most probably you'll see your problem.

Regards,
Stuart
 
C

captaincurk

Thanks Stuart!
Your problem description reads very confusing. The method for adding
new items takes no parameters, which is a bit odd. Probably that is
the source of your problem. Try to write a short summary of what
addItems should do, and most probably you'll see your problem.

I'm sorry, while simplifying my example, I of course omitted a few
details. I'll try to clarify:

The addItems function takes a stream as parameter and extracts so-
called "Types" from the stream, all of which are derived from a
TypeBase. Inside class B I maintain a list of TypeBase*, which
contains all ever added Types.

I need to be able to do this:

A* myObj = new B();
B->addItems<Type1>(stream1);
B->addItems<Type1>(stream2);
B->addItems<Type2>(stream1);

This is of course impossible, as I need addItems to be virtual,
because myObj must be of type A* (because it is contained in a list of
A*). But in the above example you can see, why I can't make B a
template class, as the user will call addItems with different Types on
the same B object.

I would like to do something like

B->addItems(stream1, (ClassPtr)Type1)

but I don't know if that is somehow possible (I made (ClassPtr) up ;))

Cheers, Jonas
 
D

DerTopper

[snip]

The addItems function takes a stream as parameter and extracts so-
called "Types" from the stream, all of which are derived from a
TypeBase. Inside class B I maintain a list of TypeBase*, which
contains all ever added Types.

I need to be able to do this:

A* myObj = new B();
B->addItems<Type1>(stream1);
B->addItems<Type1>(stream2);
B->addItems<Type2>(stream1);

This is of course impossible, as I need addItems to be virtual,
because myObj must be of type A* (because it is contained in a list of
A*).

There seems to be a conflict in semantics. I guess that the definition
of A is given by the framework (IOW, you cannot change the "interface"
A). This interface states that an object that implements this
interface can load and add some items from a stream, and -- this is
where I make a wild guess -- the object should be able to determine
what to do _solely_ by looking at what the stream contains (there may
be some magic numbers in the stream that tell you which data is
inside). I further guess that your class B needs additional
information about which types have been written into the stream. Is
this right?

Stuart
 
C

captaincurk

[snip]



The addItems function takes a stream as parameter and extracts so-
called "Types" from the stream, all of which are derived from a
TypeBase. Inside class B I maintain a list of TypeBase*, which
contains all ever added Types.
I need to be able to do this:
A* myObj = new B();
B->addItems<Type1>(stream1);
B->addItems<Type1>(stream2);
B->addItems<Type2>(stream1);
This is of course impossible, as I need addItems to be virtual,
because myObj must be of type A* (because it is contained in a list of
A*).

There seems to be a conflict in semantics. I guess that the definition
of A is given by the framework (IOW, you cannot change the "interface"
A). This interface states that an object that implements this
interface can load and add some items from a stream, and -- this is
where I make a wild guess -- the object should be able to determine
what to do _solely_ by looking at what the stream contains (there may
be some magic numbers in the stream that tell you which data is
inside). I further guess that your class B needs additional
information about which types have been written into the stream. Is
this right?

Stuart

Hi everyone,

yes, I did mean myObj instead of B, thanks for pointing that out :)

Now unfortunately the stream does not contain any information on the
kind of data. Without going into too much detail, think of an image,
which has many possible features. Each image-object can store a list
of features in the image (such as faces, edges, objects in general).
Now to add different types of features to the list, I could make
functions addFeatureX addFeatureY etc, but since I don't know what
features are available, I need to have the type of feature as a
template. Inside the addFeature function I then instantiate (giving
the image-stream as parameter) the objects of the type of feature,
which are then added to the list. This is very oversimplified. I do
not know the number of features that will be added for a specific call
to the addFeature function. Basically really I would love to just
"tell" the addFeature function which Object to instantiate. A valid
solution would be to create a function, which creates an object of a
specified type and returns it (a factory) and then pass a reference to
the factory function, which would be called inside addFeature. This I
want to avoid, as it forces the user of the classes to create such a
onstructo for every possible feature-class.

I have done it that way now, but I am still open to suggestions :)

Thank you and cheers, Jonas
 

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,989
Messages
2,570,207
Members
46,783
Latest member
RickeyDort

Latest Threads

Top