0
class A{
public:
    int var;

    virtual int getVar() { return var; }
 };

class B: public A{
public:
    int anothervar;

    int getAnotherVar() { return anothervar; }
 };


class C: public A{
public:
    int finalvar;

    int getFinalVar() { return finalvar;}
 };

int main () {
    vector<A*> myvec;

    myvec.push_back (new B());  // implying all constructors are ok
    myvec.push_back (new C());
    cout << myvec[0]->geVar();         // this works fine
    cout << myvec[0]->getAnotherVar(); // how can I do this ?
    cout << myvec[1]->getFinalVar();   // how can I do this ?
    return 0;
}

This is just a representation of another problem I'm trying to solve. So my question is, if it is possible to call derived classes methods, from a pointer vector of a base class since I cannot declare them as pure virtual at the base, because I don't want to use them in both derived.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
user2211216
  • 375
  • 2
  • 8

3 Answers3

3

You can do this by casting to the right type:

vector<A*>myvec; //pointer vector to base class
myvec.push_back(new B());  //implying all constructors are ok
myvec.push_back(new C());

cout << myvec[0]->geVar();  //this works fine
cout << myvec[1]->geVar();  //this works fine

B* b = dynamic_cast<B*>(myvec[0]);
assert(nullptr != b);
cout << b->getAnotherVar();

C* c = dynamic_cast<C*>(myvec[1]);
assert(nullptr != c);
cout << c->getFinalVar();  

However, needing to access your collection in this kind of non-uniform manner may point to a bigger class design issue.
More precisely, here it looks all fine and dandy because you create the B and C class instances in the same place where you access them, so the implicit information of which class is at which index is "local", but in a realistic example, you would probably create the objects and access them in different places, and relying on that implicit index information for the non-uniform access you want will probably be a source of bugs later.

Martin J.
  • 5,028
  • 4
  • 24
  • 41
  • thank you! could you please say more about that 'non-uniform manner' or refer me to a good reading? – user2211216 Feb 10 '14 at 12:23
  • 1
    BTW you should test result of `dynamic_cast` (or use `static_cast` since you assume it can't fail...). – Jarod42 Feb 10 '14 at 12:28
  • 2
    @OP: by non-uniform, I mean that you don't access the items in your vector using the same interface, i.e. you access methods defined in your derived classes rather than in the common base class. – Martin J. Feb 10 '14 at 12:35
  • @Jarod42: good point, I initially skipped that part for the sake of simplicity, but will edit my answer accordingly. – Martin J. Feb 10 '14 at 12:36
  • To avoid the dynamic_cast you might want to have a look at the Visitor Pattern. – duselbaer Feb 10 '14 at 12:46
0

You can only invoke methods that the type declares. If you have a base pointer to a derived object and want to invoke a method that only the derived type declares, you need to cast to that type.

If you can not be sure at compile time what the type of the object is, you need to dynamic_cast which performs a runtime check and throws an exception in case of failure.

If you can guarantee the type at compile time, static_cast is the appropriate tool.

Hulk
  • 6,399
  • 1
  • 30
  • 52
0

you need to do casting here.

cout<<static_cast<B*>(myvec[0])->getAnotherVar(); //how can i do this ?
cout<<static_cast<C*>(myvec[1])->getFinalVar();  //how can i do this ?

C++ Access derived class member from base class pointer

Community
  • 1
  • 1
Sivabushan
  • 71
  • 1
  • 8