0

The question is about C++. I have 3 classes: the first, named MovieMaker, is abstract, the second, named Actor, is derived from the first one and the third, named 'Director' derives from Actor. I want to create an array that can hold instances of both Actor and Director. How can I do that?

4
  • 4
    A director is an actor? Commented Mar 13, 2013 at 13:12
  • 3
    I know every actor wants to direct, I didn't know it went the other way, too. Commented Mar 13, 2013 at 13:13
  • 1
    I know it's not your question, but your inheritance hierarchy sounds a bit suspect. It may be worth considering a different structure. For example, you could try: MovieMaker is a concrete class; Role is abstract; Director and Actor inherit from Role and each MovieMaker has a number of Roles. This is slightly more complex, but would be more flexible and avoid weirdness for directors who don't act. Commented Mar 13, 2013 at 13:20
  • Inheritance is not the only tool available. Consider if that's what you really want. Commented Mar 13, 2013 at 13:31

2 Answers 2

3

create an array of MovieMaker pointers. it can hold pointers to derived classes. This technique is called polymorphism - here is a nice tutorial:

http://www.cplusplus.com/doc/tutorial/polymorphism/

Sign up to request clarification or add additional context in comments.

3 Comments

cplusplus.com is bad and you should feel bad
@TonyTheLion - really? I used it many times for reference before stackoverflow was around. why is it so bad?
because it has lots of errors and misinformation. Use en.cppreference.com instead.
3

Create an array of std::shared_ptr<MovieMaker>, or unique_ptr. In C++, it is usually a good idea to create a std::vector instead of a raw array: so std::vector<std::shared_ptr<MovieMaker>> vec, which you populate like this:

#include <vector>
#include <memory>

// later:
std::vector<std::shared_ptr<MovieMaker>> vec;
vec.push_back( std::make_shared<Actor>() );
vec.push_back( std::make_shared<Director>() );
vec.push_back( std::make_shared<Actor>() );

or, in C++11:

#include <vector>
#include <memory>

// later:
std::vector<std::shared_ptr<MovieMaker>> vec = {
  std::make_shared<Actor>(),
  std::make_shared<Director>(),
  std::make_shared<Actor>(),
};

If you are willing to use boost, a 3rd party library, there are a few other options.

Alternatively, create an array of boost::variant<Actor,Director>, which ignores the class hierarchy and simply stores a type-safe union like construct. boost::variant is a bit trick to use.

As another alternative, boost::any can store anything, and you can query it if what it has is what you want.

8 Comments

Well, maybe, if all the objects are allocated on the heap and the design calls for shared ownership. But that's an assumption in this answer, not part of the original question.
@PeteBecker The objects are in a std::vector already, which means they are on the free store regardless. I added a level of indirection, which (unless you a trick like boost::variant or boost::any) is required for polymorphic storage in std::vector. I chose shared_ptr rather than raw pointers, because raw pointers are more complex. unique_ptr is another alternative. I stored it in a vector, because vector is a good default container to use -- there are good reasons to use raw arrays, but they are corner cases.
Um, no, they're not already in a std::vector. But if they are, the vector manages their storage, and creating smart pointers (shared_ptr, unique_ptr, or anything else that manages storage) that point to them would create a disaster.
Sorry, my description was backwards (I justified vector after shared_ptr -- my bad). Regardless, barring union-type tricks, the only way to store polymorphic instances in C++ is in the free store. I covered a few union-type tricks that lets you store polymorophic instances in automatic storage, but they are trickier than using the free store. What, exactly, do you find missing from my explanation?
Derived d; Base &b = d; No free store here, but b acts polymorphically. More generally, if you have a container that holds pointers to a base type, it doesn't matter whether the pointed-to objects are on the free store or not; the pointers act polymorphically. But my objection is exactly what I said in my first comment: the proposed solution makes assumptions about object lifetime management that are not part of the original question. Smart pointers can be a valid part of a design, but they should not be added as a reflex action.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.