0

I have a set of classes similar to the ones shown below. However, I would like to allow users to derive from them without having to modify the base classes with additional virtual methods. Is there a way of modifying the code without having to declare virtual int GetT(void){return 0;}; in class A?

To explain the problem further, I would like to allow users to extend both A and B (or Aext and Bext) with their own methods, which are not defined as virtual methods in A and B. I am looking for a casting method that would allow casting a pointer to base class to a pointer of a derived class. In essence, I would like to use something similar to dynamic_cast<Aext*>(Trajectory[i]) if Trajectory[i] contains a pointer to the derived class, i.e. Aext.

class A {
    public:
    int a;
    A(int& ca) {a=ca;}
    virtual int GetT(void){return 0;};
};

class B{
    public:
    boost::ptr_vector<A> Trajectory;
    void PushBackStatePoint(int& ca);
};

void B::PushBackStatePoint(int& ca) {
    Trajectory.push_back(new A(ca));
}

class Aext: public A {
    public:
    int t;
    Aext(int& ca, int& ct) : A(ca) {t=ct;}
    virtual int GetT(void) {return t;}
};

class Bext: public B {
    public:
    void PushBackStatePoint(int& ca, int &ct);
    int GetFirstElement(void){return Trajectory[0].GetT();}
};

void Bext::PushBackStatePoint(int& ca, int &ct) {
    Trajectory.push_back(new Aext(ca,ct));

}

int main(){     
    Bext MyB;
    int a(5);
    int t(3);
    MyB.PushBackStatePoint(a,t);
    std::cout << MyB.GetFirstElement();
}
  • 1
    You want polymorphism without `virtual` functions? Why? And what do you mean by "modifying the base class"? – Fred Foo Jun 08 '12 at 09:43
  • You can either have virtual polymorphism or static polymorphism, but the latter requires the use of templates. If the solution you think of looks ugly then, it might be the wrong approach. Take a look at static polymorphism [link](http://en.wikipedia.org/wiki/Template_metaprogramming#Static_polymorphism). – πάντα ῥεῖ Jun 08 '12 at 09:51

2 Answers2

1

You could define the method as pure virtual in the base class, like this:

class A {
    public:
    int a;
    A(int& ca) : a(ca) {}
    virtual int GetT() = 0;
};

This makes it so the derived classes must implement GetT(), thus making class A abstract.

Also notice that I changed the constructor to use an initializer list, which is a nicer way to initialize the class members.

This may be a bit off-topic, but the way you're doing the push_back could be improved to better encapsulate the Trajectory vector, as follows:

class B{
public:
    boost::ptr_vector<A> Trajectory;
    void PushBackStatePoint(int& ca);
protected:
    void PushBackStatePoint(A *a) { Trajectory.push_back(a); }
    A getTrajectoryElement(int index) { return Trajectory[index]; }
};

void B::PushBackStatePoint(int& ca) {
    PushBackStatePoint(new A(ca));
}

class Bext: public B {
    public:
    void PushBackStatePoint(int& ca, int &ct);
    int GetFirstElement(void){return getTrajectoryElement(0).GetT();}
};

void Bext::PushBackStatePoint(int& ca, int &ct) {
    PushBackStatePoint(new Aext(ca,ct));
}

This way the base class attributes are only manipulated therein.

Brady
  • 10,207
  • 2
  • 20
  • 59
1

If you write the GetT method as:

virtual int GetT() = 0;

...instead of:

virtual int GetT(void){return 0;}

You'll make all users to implement their own GetT methods for their classes, while class A would be untouched. Also it won't be possible to create objects from class A.

So, what I am really looking for is some kind of casting method to cast a pointer to base class to pointer of a derived class.

If you later want to distinguish between object of class A or B, then you should do:

A * ptrA = dynamic_cast<A*>( Trajectory[ 0 ] );
B * ptrB = dynamic_cast<B*>( Trajectory[ 0 ] );

if ( ptrA != NULL ) {
    // more things..
}
else
if ( ptrB != NULL ) {
    // more things..
}

I am not sure this is the answer you are looking for; hope this helps, anyway.

Baltasarq
  • 12,014
  • 3
  • 38
  • 57
  • 1
    @user1391279: see [this question](http://stackoverflow.com/questions/10944106/multiple-inheritance-class-references), you want dynamic_cast – jxh Jun 08 '12 at 10:27
  • I still don't quite understand what you're trying to do. I will add the comment from @user315052. – Baltasarq Jun 08 '12 at 12:29