Please bear with me, this is my first post

So, I have this superclass called A.
And I've 2 subclasses A1 and A2.

A has attribute name.
A has function toString().

A1 inherits name, and has attribute hair.
A1 has a method toString() which goes:

string A1::toString(){
string stringA= A::toString();
stringstream info;
info<<stringA<<" "<<hair;
return info.str();
}

A2 is the same as A1, except that it has face instead of hair.
it's toString goes info<<stringA<<" "<<face;

In my main(),

vector<A*> vector;

Then, I have a function to add objects

void addA1 (vector<A*> &vector)
void addA2 (vector<A*> &vector)

both use push_back, and after testing, they work fine.

So here's the question:
I need to make another function called display().
but the tricky part is that I need to check the items in the vector, and use the correct toString() functions. Like if the first object in the vector is A1, then i'm supposed to call the toString() from A1, and if the second is A2, I call the toString() from A2.

Like so:

void display(vector<A*> &vector){
for(int c=0;c<vector.size();c++){ //traverse through vector
//If A1, use A1's toString() and display
//Else if A2, use A2's toString() and display
}
}

I was thinking it should be something like if(vector[c]==A1) or something but it gave me errors.
I'm stuck at this point.
Any help is much appreciated!

Following your logic, there are two options I can think of in this moment:
1. create a static member in each A1 and A2 to keep the description of the class and you can access it in if condition;
2. if the description of each child doesn't change, you can hardcode it like this:

class Ax: public A
{
   private:
       string description;

   public:
       string getDescription();
   ...
}

and in your main or whatever:

   if (vector[c]->getDescription() == "child_description") {...}

Note: I do not recommend the second option because if you decide later to change the ID string, you may forget where you hardcoded. Better to define the ID strings in a header of something if you want to use this method.

The point of inheritance is that you don't need to do this. The question of which version of toString to call is decided at run-time. That's the point of virtual functions. So, consider this example:

#include <iostream>
#include <vector>

class A
{
public :
    virtual void Print() const { std::cout << " A::Print !" << std::endl; }
};

class A1 : public A
{
public :
    virtual void Print() const { std::cout << "A1::Print !" << std::endl; }
};

class A2 : public A
{
public :
    virtual void Print() const { std::cout << "A2::Print !" << std::endl; }
};

int main()
{
    std::vector< A* > va;

    va.push_back( new A );
    va.push_back( new A1 );
    va.push_back( new A2 );

    for ( size_t i = 0; i < va.size(); ++i )
        va[i]->Print();

    // Tidy up
    for ( size_t i = 0; i < va.size(); ++i )
        delete va[i];

    return 0;
}

Edited 3 Years Ago by ravenous

This article has been dead for over six months. Start a new discussion instead.