What is the proper method to format and use derived classes inside of a Base* data structure?












0















Intro



I am a little lost on the proper way to hold a data structure of multiple derived classes. I am relatively new to C++, so sorry if I have idiotic errors/misconceptions.



At the moment, I use a vector<Base*>*, which makes sense to me. However, I run into some issues when I try to use the objects contained in the vector.



Issues I'm running into



I am going to use this sample set up to showcase my issues:



Base.h



class Base {

public:
Base();
Base(int a, int b);
virtual ~Base();

friend std::ostream& operator<<(std::ostream& os, Base& base);

int getA();
int getB();

protected:
int a;
int b;

};


Derived.h



class Derived : public Base {

public:
Derived(int a, int b, int c);
~Derived();

friend std::ostream& operator<<(std::ostream& os, Derived& derived);

getC();

private:
int c;

};


#1: Using member functions of the derived classes



int main() {
vector<Base*>* objects = new vector<Base*>();

Base* newbase = new Base(0, 1);
Derived newderived = new Derived(2, 3, 4);
objects.push_back(newbase);
objects.push_back(newderived);

cout << objects->front()->getA() << endl; // '0'
cout << objects->back()->getA() << endl; // '2'

cout << objects->back()->getC() << endl; // error: 'class Base' has no member named 'getC()'
}


Despite the last object in objects being an instance of class Derived, it is recognized only as class Base. This of course makes perfect sense; objects hold Base*.



While I understand why the error is occurring, I'm confused on how to solve it. In my previous searches, I found that there were two commonly proposed (and also rather debated) solutions: including every member function my different derived classes use as a virtual function in Base and using static casting.



What is the proper method/good practice for using member functions of derived classes inside of data structures containing Base*?



#2: Using friends: namely, overloading the insertion operator



int main() {

vector<Base*>* objects = new vector<Base*>();

Base* newbase = new Base(0, 1);
Derived newderived = new Derived(2, 3, 4);
objects.push_back(newbase);
objects.push_back(newderived);

cout << *(objects->front()) << endl; // Executed `Base`'s overloaded insertion operator
cout << *(objects->back()) << endl; // Also executed `Base`'s overloaded insertion operator
}


In this case, I found very little reliable suggestions for solving this problem, other than "just use a print() method instead." I understand that I could work around this issue, but I would rather understand the proper way to implement something than just avoid using it.



So, is it possible to somehow execute the derived class' overloaded insertion operator when called from a vector<Base*>? Any friend function?



#3: Identifying which derived class the object is



int main() {
vector<Base*>* objects = new vector<Base*>();

Derived newderived = new Derived(2, 3, 4);
Derived2 newderived2 = new Derived2(5, 6, 7, 8);
objects.push_back(newderived);
objects.push_back(newderived2);

if (/* objects->front() is a Derived */) cout << "Type check success << endl;
if (/* objects->back() is a Derived2 */) cout << "Type check success << endl;
}


This problem, specifically, has been addressed several times before. The two solutions I have seen is somehow evaluating what occurs after a static cast and by storing some form of type list in the base class and storing a type value in all the derived classes.



However, as I mentioned before, I am new to C++, and I don't understand the former option or the proper way to implement the second. What is the proper way to solve this problem, and are there any explained example videos or the like for me to investigate?



I know this is a bit of a long question, but it seemed to me that it was all so closely interconnected that I should keep the three sub-questions together.



Thanks for the help!










share|improve this question























  • BTW There is almost never a need to create vectors dynamically. Just do std::vector<Base*> objects;

    – Galik
    Nov 13 '18 at 2:06











  • @Galik Thank you for the quick feedback; it was very helpful. In this case, I am required to use a dynamically allocated vector (I am a student, and this is for an assignment). I think the point is to cause mistakes with stacked dereferences and the like.

    – Brendan McDonnell
    Nov 13 '18 at 3:10
















0















Intro



I am a little lost on the proper way to hold a data structure of multiple derived classes. I am relatively new to C++, so sorry if I have idiotic errors/misconceptions.



At the moment, I use a vector<Base*>*, which makes sense to me. However, I run into some issues when I try to use the objects contained in the vector.



Issues I'm running into



I am going to use this sample set up to showcase my issues:



Base.h



class Base {

public:
Base();
Base(int a, int b);
virtual ~Base();

friend std::ostream& operator<<(std::ostream& os, Base& base);

int getA();
int getB();

protected:
int a;
int b;

};


Derived.h



class Derived : public Base {

public:
Derived(int a, int b, int c);
~Derived();

friend std::ostream& operator<<(std::ostream& os, Derived& derived);

getC();

private:
int c;

};


#1: Using member functions of the derived classes



int main() {
vector<Base*>* objects = new vector<Base*>();

Base* newbase = new Base(0, 1);
Derived newderived = new Derived(2, 3, 4);
objects.push_back(newbase);
objects.push_back(newderived);

cout << objects->front()->getA() << endl; // '0'
cout << objects->back()->getA() << endl; // '2'

cout << objects->back()->getC() << endl; // error: 'class Base' has no member named 'getC()'
}


Despite the last object in objects being an instance of class Derived, it is recognized only as class Base. This of course makes perfect sense; objects hold Base*.



While I understand why the error is occurring, I'm confused on how to solve it. In my previous searches, I found that there were two commonly proposed (and also rather debated) solutions: including every member function my different derived classes use as a virtual function in Base and using static casting.



What is the proper method/good practice for using member functions of derived classes inside of data structures containing Base*?



#2: Using friends: namely, overloading the insertion operator



int main() {

vector<Base*>* objects = new vector<Base*>();

Base* newbase = new Base(0, 1);
Derived newderived = new Derived(2, 3, 4);
objects.push_back(newbase);
objects.push_back(newderived);

cout << *(objects->front()) << endl; // Executed `Base`'s overloaded insertion operator
cout << *(objects->back()) << endl; // Also executed `Base`'s overloaded insertion operator
}


In this case, I found very little reliable suggestions for solving this problem, other than "just use a print() method instead." I understand that I could work around this issue, but I would rather understand the proper way to implement something than just avoid using it.



So, is it possible to somehow execute the derived class' overloaded insertion operator when called from a vector<Base*>? Any friend function?



#3: Identifying which derived class the object is



int main() {
vector<Base*>* objects = new vector<Base*>();

Derived newderived = new Derived(2, 3, 4);
Derived2 newderived2 = new Derived2(5, 6, 7, 8);
objects.push_back(newderived);
objects.push_back(newderived2);

if (/* objects->front() is a Derived */) cout << "Type check success << endl;
if (/* objects->back() is a Derived2 */) cout << "Type check success << endl;
}


This problem, specifically, has been addressed several times before. The two solutions I have seen is somehow evaluating what occurs after a static cast and by storing some form of type list in the base class and storing a type value in all the derived classes.



However, as I mentioned before, I am new to C++, and I don't understand the former option or the proper way to implement the second. What is the proper way to solve this problem, and are there any explained example videos or the like for me to investigate?



I know this is a bit of a long question, but it seemed to me that it was all so closely interconnected that I should keep the three sub-questions together.



Thanks for the help!










share|improve this question























  • BTW There is almost never a need to create vectors dynamically. Just do std::vector<Base*> objects;

    – Galik
    Nov 13 '18 at 2:06











  • @Galik Thank you for the quick feedback; it was very helpful. In this case, I am required to use a dynamically allocated vector (I am a student, and this is for an assignment). I think the point is to cause mistakes with stacked dereferences and the like.

    – Brendan McDonnell
    Nov 13 '18 at 3:10














0












0








0








Intro



I am a little lost on the proper way to hold a data structure of multiple derived classes. I am relatively new to C++, so sorry if I have idiotic errors/misconceptions.



At the moment, I use a vector<Base*>*, which makes sense to me. However, I run into some issues when I try to use the objects contained in the vector.



Issues I'm running into



I am going to use this sample set up to showcase my issues:



Base.h



class Base {

public:
Base();
Base(int a, int b);
virtual ~Base();

friend std::ostream& operator<<(std::ostream& os, Base& base);

int getA();
int getB();

protected:
int a;
int b;

};


Derived.h



class Derived : public Base {

public:
Derived(int a, int b, int c);
~Derived();

friend std::ostream& operator<<(std::ostream& os, Derived& derived);

getC();

private:
int c;

};


#1: Using member functions of the derived classes



int main() {
vector<Base*>* objects = new vector<Base*>();

Base* newbase = new Base(0, 1);
Derived newderived = new Derived(2, 3, 4);
objects.push_back(newbase);
objects.push_back(newderived);

cout << objects->front()->getA() << endl; // '0'
cout << objects->back()->getA() << endl; // '2'

cout << objects->back()->getC() << endl; // error: 'class Base' has no member named 'getC()'
}


Despite the last object in objects being an instance of class Derived, it is recognized only as class Base. This of course makes perfect sense; objects hold Base*.



While I understand why the error is occurring, I'm confused on how to solve it. In my previous searches, I found that there were two commonly proposed (and also rather debated) solutions: including every member function my different derived classes use as a virtual function in Base and using static casting.



What is the proper method/good practice for using member functions of derived classes inside of data structures containing Base*?



#2: Using friends: namely, overloading the insertion operator



int main() {

vector<Base*>* objects = new vector<Base*>();

Base* newbase = new Base(0, 1);
Derived newderived = new Derived(2, 3, 4);
objects.push_back(newbase);
objects.push_back(newderived);

cout << *(objects->front()) << endl; // Executed `Base`'s overloaded insertion operator
cout << *(objects->back()) << endl; // Also executed `Base`'s overloaded insertion operator
}


In this case, I found very little reliable suggestions for solving this problem, other than "just use a print() method instead." I understand that I could work around this issue, but I would rather understand the proper way to implement something than just avoid using it.



So, is it possible to somehow execute the derived class' overloaded insertion operator when called from a vector<Base*>? Any friend function?



#3: Identifying which derived class the object is



int main() {
vector<Base*>* objects = new vector<Base*>();

Derived newderived = new Derived(2, 3, 4);
Derived2 newderived2 = new Derived2(5, 6, 7, 8);
objects.push_back(newderived);
objects.push_back(newderived2);

if (/* objects->front() is a Derived */) cout << "Type check success << endl;
if (/* objects->back() is a Derived2 */) cout << "Type check success << endl;
}


This problem, specifically, has been addressed several times before. The two solutions I have seen is somehow evaluating what occurs after a static cast and by storing some form of type list in the base class and storing a type value in all the derived classes.



However, as I mentioned before, I am new to C++, and I don't understand the former option or the proper way to implement the second. What is the proper way to solve this problem, and are there any explained example videos or the like for me to investigate?



I know this is a bit of a long question, but it seemed to me that it was all so closely interconnected that I should keep the three sub-questions together.



Thanks for the help!










share|improve this question














Intro



I am a little lost on the proper way to hold a data structure of multiple derived classes. I am relatively new to C++, so sorry if I have idiotic errors/misconceptions.



At the moment, I use a vector<Base*>*, which makes sense to me. However, I run into some issues when I try to use the objects contained in the vector.



Issues I'm running into



I am going to use this sample set up to showcase my issues:



Base.h



class Base {

public:
Base();
Base(int a, int b);
virtual ~Base();

friend std::ostream& operator<<(std::ostream& os, Base& base);

int getA();
int getB();

protected:
int a;
int b;

};


Derived.h



class Derived : public Base {

public:
Derived(int a, int b, int c);
~Derived();

friend std::ostream& operator<<(std::ostream& os, Derived& derived);

getC();

private:
int c;

};


#1: Using member functions of the derived classes



int main() {
vector<Base*>* objects = new vector<Base*>();

Base* newbase = new Base(0, 1);
Derived newderived = new Derived(2, 3, 4);
objects.push_back(newbase);
objects.push_back(newderived);

cout << objects->front()->getA() << endl; // '0'
cout << objects->back()->getA() << endl; // '2'

cout << objects->back()->getC() << endl; // error: 'class Base' has no member named 'getC()'
}


Despite the last object in objects being an instance of class Derived, it is recognized only as class Base. This of course makes perfect sense; objects hold Base*.



While I understand why the error is occurring, I'm confused on how to solve it. In my previous searches, I found that there were two commonly proposed (and also rather debated) solutions: including every member function my different derived classes use as a virtual function in Base and using static casting.



What is the proper method/good practice for using member functions of derived classes inside of data structures containing Base*?



#2: Using friends: namely, overloading the insertion operator



int main() {

vector<Base*>* objects = new vector<Base*>();

Base* newbase = new Base(0, 1);
Derived newderived = new Derived(2, 3, 4);
objects.push_back(newbase);
objects.push_back(newderived);

cout << *(objects->front()) << endl; // Executed `Base`'s overloaded insertion operator
cout << *(objects->back()) << endl; // Also executed `Base`'s overloaded insertion operator
}


In this case, I found very little reliable suggestions for solving this problem, other than "just use a print() method instead." I understand that I could work around this issue, but I would rather understand the proper way to implement something than just avoid using it.



So, is it possible to somehow execute the derived class' overloaded insertion operator when called from a vector<Base*>? Any friend function?



#3: Identifying which derived class the object is



int main() {
vector<Base*>* objects = new vector<Base*>();

Derived newderived = new Derived(2, 3, 4);
Derived2 newderived2 = new Derived2(5, 6, 7, 8);
objects.push_back(newderived);
objects.push_back(newderived2);

if (/* objects->front() is a Derived */) cout << "Type check success << endl;
if (/* objects->back() is a Derived2 */) cout << "Type check success << endl;
}


This problem, specifically, has been addressed several times before. The two solutions I have seen is somehow evaluating what occurs after a static cast and by storing some form of type list in the base class and storing a type value in all the derived classes.



However, as I mentioned before, I am new to C++, and I don't understand the former option or the proper way to implement the second. What is the proper way to solve this problem, and are there any explained example videos or the like for me to investigate?



I know this is a bit of a long question, but it seemed to me that it was all so closely interconnected that I should keep the three sub-questions together.



Thanks for the help!







c++ inheritance vector derived-class base-class






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 13 '18 at 1:32









Brendan McDonnellBrendan McDonnell

404




404













  • BTW There is almost never a need to create vectors dynamically. Just do std::vector<Base*> objects;

    – Galik
    Nov 13 '18 at 2:06











  • @Galik Thank you for the quick feedback; it was very helpful. In this case, I am required to use a dynamically allocated vector (I am a student, and this is for an assignment). I think the point is to cause mistakes with stacked dereferences and the like.

    – Brendan McDonnell
    Nov 13 '18 at 3:10



















  • BTW There is almost never a need to create vectors dynamically. Just do std::vector<Base*> objects;

    – Galik
    Nov 13 '18 at 2:06











  • @Galik Thank you for the quick feedback; it was very helpful. In this case, I am required to use a dynamically allocated vector (I am a student, and this is for an assignment). I think the point is to cause mistakes with stacked dereferences and the like.

    – Brendan McDonnell
    Nov 13 '18 at 3:10

















BTW There is almost never a need to create vectors dynamically. Just do std::vector<Base*> objects;

– Galik
Nov 13 '18 at 2:06





BTW There is almost never a need to create vectors dynamically. Just do std::vector<Base*> objects;

– Galik
Nov 13 '18 at 2:06













@Galik Thank you for the quick feedback; it was very helpful. In this case, I am required to use a dynamically allocated vector (I am a student, and this is for an assignment). I think the point is to cause mistakes with stacked dereferences and the like.

– Brendan McDonnell
Nov 13 '18 at 3:10





@Galik Thank you for the quick feedback; it was very helpful. In this case, I am required to use a dynamically allocated vector (I am a student, and this is for an assignment). I think the point is to cause mistakes with stacked dereferences and the like.

– Brendan McDonnell
Nov 13 '18 at 3:10












2 Answers
2






active

oldest

votes


















1














IMO all of your problems stem from trying to fight against your chosen solution - dynamic polymorphism.



That technique works best when every derived type shares a common interface. The whole point of dynamic polymorphism is that the calling code does not need to know or care what the actual type is, it only cares that it uses a specific interface.



In your example:



1) You are trying to use two different interfaces. Your dynamic
polymorphism is acting through the Base interface and you want to use the Derived interface. With dynamic polymorphism pick your interface. If you need to know the specific type in a given part of the system then polymorphism is simply not the best solution in that area of the code.



2) The proper way to do that is to add a print() function. The idea is that every derived type knows how to print itself so that the calling code doesn't need to know or care how that is done.



3) In parts of the system where dynamic polymorphism fails (where you need to know the concrete type of the object) then the recommended way to discover the type is using a dynamic_cast:



if(auto derived = dynamic_cast<Derived*>(objects->front()))
{
derived->getC(); // Derived specific calls
}


If the pointer is of the wrong type a nullptr is returned and the if() fails.



What I have found with C++ is that dynamic polymorphism is really not the best solution for a lot of problems. There can be a temptation to try to make everything dynamically polymorphic but IMO that only works well for a given subset of object oriented design problems.



C++ also excels in other areas such as static polymorphism (using the template engine) and procedural polymorphism (function overloading). These are well worth exploring too.






share|improve this answer

































    1














    You are implementing a non-abstract base class. In polymorphism, trying to seek if a method exists in the base/derived class is considered a wrong program practice. Declare the common methods instead as virtual. Try this like so.



    class Base {

    public:
    Base();
    Base(int a, int b);
    virtual ~Base();

    friend std::ostream& operator<<(std::ostream& os, Base& base);

    virtual int getA();
    virtual int getB();
    virtual int getC() { return 0; }

    protected:
    int a;
    int b;

    };

    class Derived : public Base {

    public:
    Derived(int a, int b, int c);
    ~Derived();

    friend std::ostream& operator<<(std::ostream& os, Derived& derived);

    virtual int getA();
    virtual int getB();
    virtual int getC();

    private:
    int c;

    };

    int main() {
    vector<Base*> objects;

    Base* newbase = new Base(0, 1);
    Derived newderived = Derived(2, 3, 4);
    Base* pnewderived = &newderived;
    objects.push_back(newbase);
    objects.push_back(pnewderived);

    cout << objects.front()->getA() << endl;
    cout << objects.back()->getA() << endl;

    cout << objects.back()->getC() << endl;
    }





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272490%2fwhat-is-the-proper-method-to-format-and-use-derived-classes-inside-of-a-base-da%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      IMO all of your problems stem from trying to fight against your chosen solution - dynamic polymorphism.



      That technique works best when every derived type shares a common interface. The whole point of dynamic polymorphism is that the calling code does not need to know or care what the actual type is, it only cares that it uses a specific interface.



      In your example:



      1) You are trying to use two different interfaces. Your dynamic
      polymorphism is acting through the Base interface and you want to use the Derived interface. With dynamic polymorphism pick your interface. If you need to know the specific type in a given part of the system then polymorphism is simply not the best solution in that area of the code.



      2) The proper way to do that is to add a print() function. The idea is that every derived type knows how to print itself so that the calling code doesn't need to know or care how that is done.



      3) In parts of the system where dynamic polymorphism fails (where you need to know the concrete type of the object) then the recommended way to discover the type is using a dynamic_cast:



      if(auto derived = dynamic_cast<Derived*>(objects->front()))
      {
      derived->getC(); // Derived specific calls
      }


      If the pointer is of the wrong type a nullptr is returned and the if() fails.



      What I have found with C++ is that dynamic polymorphism is really not the best solution for a lot of problems. There can be a temptation to try to make everything dynamically polymorphic but IMO that only works well for a given subset of object oriented design problems.



      C++ also excels in other areas such as static polymorphism (using the template engine) and procedural polymorphism (function overloading). These are well worth exploring too.






      share|improve this answer






























        1














        IMO all of your problems stem from trying to fight against your chosen solution - dynamic polymorphism.



        That technique works best when every derived type shares a common interface. The whole point of dynamic polymorphism is that the calling code does not need to know or care what the actual type is, it only cares that it uses a specific interface.



        In your example:



        1) You are trying to use two different interfaces. Your dynamic
        polymorphism is acting through the Base interface and you want to use the Derived interface. With dynamic polymorphism pick your interface. If you need to know the specific type in a given part of the system then polymorphism is simply not the best solution in that area of the code.



        2) The proper way to do that is to add a print() function. The idea is that every derived type knows how to print itself so that the calling code doesn't need to know or care how that is done.



        3) In parts of the system where dynamic polymorphism fails (where you need to know the concrete type of the object) then the recommended way to discover the type is using a dynamic_cast:



        if(auto derived = dynamic_cast<Derived*>(objects->front()))
        {
        derived->getC(); // Derived specific calls
        }


        If the pointer is of the wrong type a nullptr is returned and the if() fails.



        What I have found with C++ is that dynamic polymorphism is really not the best solution for a lot of problems. There can be a temptation to try to make everything dynamically polymorphic but IMO that only works well for a given subset of object oriented design problems.



        C++ also excels in other areas such as static polymorphism (using the template engine) and procedural polymorphism (function overloading). These are well worth exploring too.






        share|improve this answer




























          1












          1








          1







          IMO all of your problems stem from trying to fight against your chosen solution - dynamic polymorphism.



          That technique works best when every derived type shares a common interface. The whole point of dynamic polymorphism is that the calling code does not need to know or care what the actual type is, it only cares that it uses a specific interface.



          In your example:



          1) You are trying to use two different interfaces. Your dynamic
          polymorphism is acting through the Base interface and you want to use the Derived interface. With dynamic polymorphism pick your interface. If you need to know the specific type in a given part of the system then polymorphism is simply not the best solution in that area of the code.



          2) The proper way to do that is to add a print() function. The idea is that every derived type knows how to print itself so that the calling code doesn't need to know or care how that is done.



          3) In parts of the system where dynamic polymorphism fails (where you need to know the concrete type of the object) then the recommended way to discover the type is using a dynamic_cast:



          if(auto derived = dynamic_cast<Derived*>(objects->front()))
          {
          derived->getC(); // Derived specific calls
          }


          If the pointer is of the wrong type a nullptr is returned and the if() fails.



          What I have found with C++ is that dynamic polymorphism is really not the best solution for a lot of problems. There can be a temptation to try to make everything dynamically polymorphic but IMO that only works well for a given subset of object oriented design problems.



          C++ also excels in other areas such as static polymorphism (using the template engine) and procedural polymorphism (function overloading). These are well worth exploring too.






          share|improve this answer















          IMO all of your problems stem from trying to fight against your chosen solution - dynamic polymorphism.



          That technique works best when every derived type shares a common interface. The whole point of dynamic polymorphism is that the calling code does not need to know or care what the actual type is, it only cares that it uses a specific interface.



          In your example:



          1) You are trying to use two different interfaces. Your dynamic
          polymorphism is acting through the Base interface and you want to use the Derived interface. With dynamic polymorphism pick your interface. If you need to know the specific type in a given part of the system then polymorphism is simply not the best solution in that area of the code.



          2) The proper way to do that is to add a print() function. The idea is that every derived type knows how to print itself so that the calling code doesn't need to know or care how that is done.



          3) In parts of the system where dynamic polymorphism fails (where you need to know the concrete type of the object) then the recommended way to discover the type is using a dynamic_cast:



          if(auto derived = dynamic_cast<Derived*>(objects->front()))
          {
          derived->getC(); // Derived specific calls
          }


          If the pointer is of the wrong type a nullptr is returned and the if() fails.



          What I have found with C++ is that dynamic polymorphism is really not the best solution for a lot of problems. There can be a temptation to try to make everything dynamically polymorphic but IMO that only works well for a given subset of object oriented design problems.



          C++ also excels in other areas such as static polymorphism (using the template engine) and procedural polymorphism (function overloading). These are well worth exploring too.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 13 '18 at 2:08

























          answered Nov 13 '18 at 2:03









          GalikGalik

          33.6k34876




          33.6k34876

























              1














              You are implementing a non-abstract base class. In polymorphism, trying to seek if a method exists in the base/derived class is considered a wrong program practice. Declare the common methods instead as virtual. Try this like so.



              class Base {

              public:
              Base();
              Base(int a, int b);
              virtual ~Base();

              friend std::ostream& operator<<(std::ostream& os, Base& base);

              virtual int getA();
              virtual int getB();
              virtual int getC() { return 0; }

              protected:
              int a;
              int b;

              };

              class Derived : public Base {

              public:
              Derived(int a, int b, int c);
              ~Derived();

              friend std::ostream& operator<<(std::ostream& os, Derived& derived);

              virtual int getA();
              virtual int getB();
              virtual int getC();

              private:
              int c;

              };

              int main() {
              vector<Base*> objects;

              Base* newbase = new Base(0, 1);
              Derived newderived = Derived(2, 3, 4);
              Base* pnewderived = &newderived;
              objects.push_back(newbase);
              objects.push_back(pnewderived);

              cout << objects.front()->getA() << endl;
              cout << objects.back()->getA() << endl;

              cout << objects.back()->getC() << endl;
              }





              share|improve this answer




























                1














                You are implementing a non-abstract base class. In polymorphism, trying to seek if a method exists in the base/derived class is considered a wrong program practice. Declare the common methods instead as virtual. Try this like so.



                class Base {

                public:
                Base();
                Base(int a, int b);
                virtual ~Base();

                friend std::ostream& operator<<(std::ostream& os, Base& base);

                virtual int getA();
                virtual int getB();
                virtual int getC() { return 0; }

                protected:
                int a;
                int b;

                };

                class Derived : public Base {

                public:
                Derived(int a, int b, int c);
                ~Derived();

                friend std::ostream& operator<<(std::ostream& os, Derived& derived);

                virtual int getA();
                virtual int getB();
                virtual int getC();

                private:
                int c;

                };

                int main() {
                vector<Base*> objects;

                Base* newbase = new Base(0, 1);
                Derived newderived = Derived(2, 3, 4);
                Base* pnewderived = &newderived;
                objects.push_back(newbase);
                objects.push_back(pnewderived);

                cout << objects.front()->getA() << endl;
                cout << objects.back()->getA() << endl;

                cout << objects.back()->getC() << endl;
                }





                share|improve this answer


























                  1












                  1








                  1







                  You are implementing a non-abstract base class. In polymorphism, trying to seek if a method exists in the base/derived class is considered a wrong program practice. Declare the common methods instead as virtual. Try this like so.



                  class Base {

                  public:
                  Base();
                  Base(int a, int b);
                  virtual ~Base();

                  friend std::ostream& operator<<(std::ostream& os, Base& base);

                  virtual int getA();
                  virtual int getB();
                  virtual int getC() { return 0; }

                  protected:
                  int a;
                  int b;

                  };

                  class Derived : public Base {

                  public:
                  Derived(int a, int b, int c);
                  ~Derived();

                  friend std::ostream& operator<<(std::ostream& os, Derived& derived);

                  virtual int getA();
                  virtual int getB();
                  virtual int getC();

                  private:
                  int c;

                  };

                  int main() {
                  vector<Base*> objects;

                  Base* newbase = new Base(0, 1);
                  Derived newderived = Derived(2, 3, 4);
                  Base* pnewderived = &newderived;
                  objects.push_back(newbase);
                  objects.push_back(pnewderived);

                  cout << objects.front()->getA() << endl;
                  cout << objects.back()->getA() << endl;

                  cout << objects.back()->getC() << endl;
                  }





                  share|improve this answer













                  You are implementing a non-abstract base class. In polymorphism, trying to seek if a method exists in the base/derived class is considered a wrong program practice. Declare the common methods instead as virtual. Try this like so.



                  class Base {

                  public:
                  Base();
                  Base(int a, int b);
                  virtual ~Base();

                  friend std::ostream& operator<<(std::ostream& os, Base& base);

                  virtual int getA();
                  virtual int getB();
                  virtual int getC() { return 0; }

                  protected:
                  int a;
                  int b;

                  };

                  class Derived : public Base {

                  public:
                  Derived(int a, int b, int c);
                  ~Derived();

                  friend std::ostream& operator<<(std::ostream& os, Derived& derived);

                  virtual int getA();
                  virtual int getB();
                  virtual int getC();

                  private:
                  int c;

                  };

                  int main() {
                  vector<Base*> objects;

                  Base* newbase = new Base(0, 1);
                  Derived newderived = Derived(2, 3, 4);
                  Base* pnewderived = &newderived;
                  objects.push_back(newbase);
                  objects.push_back(pnewderived);

                  cout << objects.front()->getA() << endl;
                  cout << objects.back()->getA() << endl;

                  cout << objects.back()->getC() << endl;
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 13 '18 at 2:01









                  seccpurseccpur

                  2,4352514




                  2,4352514






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272490%2fwhat-is-the-proper-method-to-format-and-use-derived-classes-inside-of-a-base-da%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Florida Star v. B. J. F.

                      Error while running script in elastic search , gateway timeout

                      Adding quotations to stringified JSON object values