-2

For my project I have this class structure :

class Base
{
        enum class type
    {
        Derived1,
        Derived2
    }

    int getType() {return type;};

    type        type;
    //general methods & attributes
}

class Derived1 : public Base
{
    //specific methods & attributes
    void        uniqueSpecificMethodOfDerived1();
}

class Derived2 : public Base
{
    //specific methods & attributes
    void        uniqueSpecificMethodOfDerived2();
}

class Core
{
    vector<unique_ptr<Base>>        tab;
    void                            iterate();
}

void        Core::iterate()
{
    tab.emplace_back(new Derived1());
    tab.emplace_back(new Derived2());

    vector<unique_ptr<Base>>::iterator it;

    for (it = tab.begin(); it != tab.end(); ++it)
    {
        if ((*it)->getType())
            (*it)->uniqueSpecificMethodOfDerived1(); //unknow function Can't resolve 'uniqueSpecificMethodOfDerived1()'
        if ((*it)->getType())
            (*it)->uniqueSpecificMethodOfDerived2(); //unknow function Can't resolve 'uniqueSpecificMethodOfDerived1()'
    }
}

My problem is I can't reach the specific methods of derived class in this vector. And I do not want to use polymorphism because this functions are totally different and not needed by other derived classes.

How I can do that ?

doums
  • 470
  • 10
  • 24
  • 3
    If these functions are totally different, why did you stuff these different objects into the same vector? – Quentin Apr 10 '17 at 16:14
  • 1
    You'd at least need to downcast your pointers to the correct type (using `dynamic_cast`) - the `Base` class obviously knows nothing about the methods of its children (since they aren't virtual) [I'm assuming you have actual inheritance - also this way of doing things kind of defeats the purpose of inheritance] – UnholySheep Apr 10 '17 at 16:17
  • Because these derivative classes share many methods and attributes that the main class gives. Really they are objects of the same type. Entity is my base class, Enemy/Player/Shot are derived classes of Entity – doums Apr 10 '17 at 16:18
  • cant you make the code a bit less pseudo ? DId you mean `class Derived : public Base` ? Is `void iterate()` actually `void Core::iterate()` ? – 463035818_is_not_an_ai Apr 10 '17 at 16:20
  • yes sorry I have edit my code! – doums Apr 10 '17 at 16:20
  • 1
    You should probably look into [Composition over Inheritance](http://stackoverflow.com/questions/3441090/what-is-composition-as-it-relates-to-object-oriented-design) - I have a suspicion it's better suited for your needs – UnholySheep Apr 10 '17 at 16:22
  • 1
    Accessing members of a derived type non-virtually through a pointer/reference to a base type is an anti-pattern, and is indicative of a bad class model. You probably need to rethink your design. – cdhowie Apr 10 '17 at 16:26
  • You're doing it wrong. A base class is supposed to present an interface that derived classes implement. Reuse via inheritance is the wrong thing to do. – Rob K Apr 10 '17 at 16:53

1 Answers1

1

My problem is I can't reach the specific methods of derived class in this vector. And I do not want to use polymorphism because this functions are totally different and not needed by other derived classes.

How I can do that ?

The language provides two mechanisms to access functions in a derived class given a pointer/reference to base class.

  1. Through polymorphism.
  2. Through dynmaic_cast and accessing the derived class function directly.

You can build layers of functions that allow you to access the direct interface of a derived class without the client code explicitly using dynamic_cast but they must use dynamic_cast at some point if use of polymorphism is not an option.

Here's an updated version of your code that uses dynamic_cast directly.

class Base
{
   public:
      virtual ~Base() {}
};

class Derived1 : public Base
{
   public:
      void uniqueSpecificMethodOfDerived1() {}
};

class Derived2 : public Base
{
   public:
      void uniqueSpecificMethodOfDerived2(){}
};

class Core
{
   vector<unique_ptr<Base>>        tab;
   void                            iterate();
};

void Core::iterate()
{
   tab.emplace_back(new Derived1());
   tab.emplace_back(new Derived2());

   vector<unique_ptr<Base>>::iterator it;

   for (it = tab.begin(); it != tab.end(); ++it)
   {
      Base* ptr = (*it).get();
      Derived1* ptr1 = nullptr;
      Derived2* ptr2 = nullptr;
      if ( (ptr1 = dynamic_cast<Derived1*>(ptr)) != nullptr )
      {
         ptr1->uniqueSpecificMethodOfDerived1();
      }

      if ( (ptr2 = dynamic_cast<Derived2*>(ptr)) != nullptr )
      {
         ptr2->uniqueSpecificMethodOfDerived2();
      }
   }
}
Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270