有没有办法避免在特定的自定义类继承结构中使用虚方法?

时间:2012-06-08 09:38:28

标签: c++ oop inheritance polymorphism virtual

我有一组类似于下面显示的类。但是,我想允许用户从它们派生而不必使用其他虚拟方法修改基类。有没有办法修改代码而无需在类virtual int GetT(void){return 0;};中声明A

为了进一步解释这个问题,我想允许用户使用自己的方法扩展AB(或AextBext)未在AB中定义为虚拟方法。我正在寻找一种转换方法,允许将指向基类的指针转换为派生类的指针。实质上,如果dynamic_cast<Aext*>(Trajectory[i])包含指向派生类的指针,即Trajectory[i],我想使用与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();
}

2 个答案:

答案 0 :(得分:1)

您可以在基类中将方法定义为纯虚拟,如下所示:

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

这使得派生类必须实现GetT(),从而使A类成为抽象。

另请注意,我更改了构造函数以使用初始化列表,这是一种初始化类成员的更好方法。

这可能有点偏离主题,但是你可以改进你做push_back的方式以更好地封装Trajectory向量,如下所示:

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));
}

这样只能在其中操纵基类属性。

答案 1 :(得分:1)

如果您将GetT方法编写为:

virtual int GetT() = 0;

...而不是:

virtual int GetT(void){return 0;}

您将让所有用户为他们的类实现自己的GetT方法,而A类则不会受到影响。此外,无法从A类创建对象。

  

所以,我真正想要的是某种铸造方法   将指向基类的指针强制转换为派生类的指针。

如果您以后想要区分A类或B类的对象,那么您应该这样做:

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..
}

我不确定这是你正在寻找的答案;无论如何,希望这会有所帮助。