2

So here is my dilemma:

I have a base class (Let's say a generic Person class):

class Person{
public:
    Person();
    ~Person();
    virtual void Init();
    virtual void SaySomething();
};

Now I want to have other classes inherit these methods.

class Worker: public Person{
public:

   Worker();
   ~Worker();

   void Init(){
     // would do some special initializing.
   }

   void SaySomething(){
     // Print something about the worker.
   }

};

Now I would have a manager class:

class Manager{
public:

   void Init();
   void Run();

   void SwitchPerson(Person* p);

protected:
   vector<Person*> people;
};

The example I have given with the Worker being the child class of a Person is probably not the best. But the point is not the content of the class, it's the inheritance, and more specifically how classes understand and know of other classes.

Now in my main function I would have the following:

int main()
{
  Manager* m = new Manager();
  m->Init();

  // Create a new worker;
  Person* w = new Worker();

  m->SwitchPerson(w);

  return 0;
}

Now I am not sure if this is the right way of approaching the problem. The problem is that there can be unlimited amount of child classes and the manager class can't know about them. The manager class only knows about the parent (Person) class. So the SwitchPerson would add the new Worker class of type Person(Now i'm not sure if this is structurally incorrect, I have a feeling it is.) to the vector. But first it needs to make sure that there are no Worker Classes already in the vector. I tried using typeid.name but this obviously returns the name of the parent(Person) class.

I thought of using a template with a vector.. but again that would require the manager class to know about the Worker or any other children classes.

If you need me to explain anything else or add any relevant information just let me know.

EDIT:

Note: The terms Person, Worker, and Manager is irrelevant. It could be Camera, Lens, and Stage for all that matters.

SwitchPerson:

Let's say only one person could be active at once. It would make even more sense with the Camera, Lens, and Stage analogy. As only one camera can go to the screen lets say.

Let's say we are keeping with the Camera analogy. We have our first scene and we first call SwitchCamera() and pass in the new Camera. But the problem is the Stage object (Which would be the manager) does not know about the lens or the different types of lenses. There could be 100 or 10000. It doesn't matter. The Scene only knows about the camera which is a base class to all of the lens classes.

So when we switchCamera() we can then utilize the object to control the lens let's say (not very realistic but whatever). All of the controls are implemented first as virtual members inside the Camera base class. So the lenses classes all have the same members.

Now you have finished with the first scene and want to switch camera again. You would once again call SwitchCamera() and pass in the new second camera. In the switch camera the goal would be to set the passed camera object as it's active camera, then push it to the vector.

But we dont want two copies of the same lenses. This is where the problem lies. I want to be able to check whether the passed in Camera* camera = new Lense123(); is already inside the vector. If it is then I want to use the original one and discard the newly passed one.

Daniel
  • 1,692
  • 2
  • 13
  • 19
  • 2
    `Manager m();` doesn't create object `m`. [Most vexing parse](http://en.wikipedia.org/wiki/Most_vexing_parse). Any decent compiler should warn it. – Mahesh Jun 14 '12 at 03:57
  • I just wrote the code really quickly, the real implementation of the problem is not related to Person, Worker, or Manager. – Daniel Jun 14 '12 at 04:03
  • Make the person Abstract-Class maybe? – Memos Electron Jun 14 '12 at 04:04
  • 1
    You're mostly there. However, can you explain this bit: *o the SwitchPerson would add the new Worker class of type Person(Now i'm not sure if this is structurally incorrect, I have a feeling it is.) to the vector. But first it needs to make sure that there are no Worker Classes already in the vector.*? – dirkgently Jun 14 '12 at 04:05
  • Edited my post to provide a better analogy and better explain the SwitchPerson or now SwitchCamera. – Daniel Jun 14 '12 at 04:16
  • @memosdp The Person class isn't really the problem. The problem is How I can make sure Manager / Scene doesn't know about the different child classes of Person but can still store then inside the vector. – Daniel Jun 14 '12 at 04:18
  • @Daniel: You need a `std::unordered_set` of `Lens` objects within your `Stage` class. You will need to define a hash function though for your `std::unordered_set` objects. There is also this little thing about terminology. You say your `Lens` derives from `Camera`. That doesn't sound right. A `Camera` [has-a](http://en.wikipedia.org/wiki/Has-a) `Lens`. It is containment not inheritance. – dirkgently Jun 14 '12 at 04:55
  • Make the destructor of your base classes virtual in this case. http://stackoverflow.com/questions/1123044/when-should-your-destructor-be-virtual – Sanish Jun 14 '12 at 05:07
  • @dirkgently Yes Lens being a child of Camera doesn't make sense in real life example but this was purely an analogy. The contents or names of the classes are irrelevant. The problem was to define the scope of how Manager / Scene cannot have knowledge of subclasses to Person / Camera but can still check if a subclass was already in the vector. – Daniel Jun 14 '12 at 05:25
  • @Daniel: I'd suggest you take a look at `unordered_set` instead of using `vector` (and do a O(N) check everytime before inserting). You may just end up with better performance and a more idiomatic and simpler codebase. Cheers! – dirkgently Jun 14 '12 at 05:38

2 Answers2

3

It sounds like you want Manager to have a vector of unique Persons, ie you can have a Worker, and a Person, and a ThirdPerson, but not more than one of each in the vector? Why not just overload a function in Person that returns a string label of the subclass and iterate through the vector calling pPerson->GetLabel() for each, and comparing it to the label of the new object you're thinking of adding to the vector.

Manager still only knows about the Person class, doesn't have to know anything about the different subclasses of Person, but can get a unique string back from each type.

jacobsee
  • 1,438
  • 4
  • 18
  • 34
  • And you have cracked my code sir. This is exactly what I was looking for, and of course it ended up being as simple as that. Thank you! :) – Daniel Jun 14 '12 at 04:22
  • Instead of overloading GetLabel() I simply added a string m_label in the Person class as Protected. In the person class theres a GetLabel method that returns m_label. m_label is set inside the Worker or any subclasses constructor. – Daniel Jun 14 '12 at 06:03
0

A Manager is a Person, not a Manager has a Person. I would inherit Manager from Person, and a Manager has 1...N Employees, so the best thing to do is: Inherit Manager from Person Have a vector in Manager. I would make the class Person virtual, so no one could implement a "Person"

cybertextron
  • 10,547
  • 28
  • 104
  • 208
  • I guess I didn't clarify... Manager was just a class name to Manage the Person objects. It's not related to Person or Worker. and also Person, Worker, and Manager is irrelevant. It would be Camera, Lens, and Stage. the part i'm trying to get right is how Manager / Stage cannot know of the child elements but still have a vector of them? – Daniel Jun 14 '12 at 04:05