4

I'm still pretty new to c++ (coming over from java). I have a stl list of type Actor. When Actor only contained "real" methods there was no problem. I now want to extend this class to several classes, and have a need to change some methods to be abstract, since they don't make sense as concrete anymore.

As I expected (from the documentation) this is bad news because you can no longer instantiate Actor, and so when I iterate through my list I run into problems.

What is the c++ way to do this?

Sorry if there's anything unclear

2
  • Could you clarify things a little bit? Do you have a vector<Actor> (probably won't work) or do you have a vector<Actor*>? Commented Aug 10, 2009 at 19:43
  • I have vector <Actor> which I now realize is the problem. Commented Aug 10, 2009 at 19:53

3 Answers 3

6

You can not handle this directly:

As you can see when the class is abstract you can not instanciate the object.
Even if the class where not abstract you would not be able to put derived objects into the list because of the slicing problem.
The solution is to use pointers.

So the first question is who owns the pointer (it is the responcability of the owner to delete it when its life time is over).

With a std::list<> the list took ownership by creating a copy of the object and taking ownership of the copy. But the destructor of a pointer does nothing. You need to manually call the delete on a pointer to get the destructor of the obejct to activate. So std::list<> is not a good option for holding pointers when it also needs to take ownership.

Solution 1:

// Objects are owned by the scope, the list just holds apointer. ActorD1 a1; Actor D1 derived from Actor ActorD2 a2; ActorD2 a3; std::list<Actor*> actorList; actorList.push_back(&a1); actorList.push_back(&a2); actorList.push_back(&a3); 

This works fine as the list will go out of scope then the objects everything works fine. But this is not very useful for dynamically (run-time) created objects.

Solution 2:

Boost provides a set of containers that handle pointers. You give ownership of the pointer to the container and the object is destroyed by the containter when the container goes out ofd scope.

boost::ptr_list<Actor> actorList; actorList.push_back(new ActorD1); actorList.push_back(new ActorD2); actorList.push_back(new ActorD2); 
Sign up to request clarification or add additional context in comments.

1 Comment

Don't you mean std::list<Actor *> actorList; instead of std::list<Actor> actorList;?
2

It's not possible to create a std::list<Actor> if the type Actor is abstract. Under the hood a list will hold an instance of the type specified in the template arguments. Because you can't ever have an instance of an abstract class this won't ever work.

What you can do though is use a level of indirection like a pointer. It is legal to have an instance of a pointer to an abstract class and hence legal to make a stl::list<Actor*>.

Comments

2

STL containers are designed for copyable types. You should look into Boost pointer containers and/or smart pointers for storing polymorphic type instances in a collection.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.