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



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

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

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

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

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

另请注意,我将构造函数更改为使用初始值设定项列表,这是初始化类成员的更好方法。

这可能有点跑题,但可以改进您执行push_back的方式,以更好地封装轨迹向量,如下所示:

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

这样,基类属性仅在其中进行操作。

如果将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..
}

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

最新更新