0

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

为了进一步解释这个问题,我想允许用户使用他们自己的方法来扩展Aand B(或Aextand ),这些方法在and中没有定义为虚拟方法。我正在寻找一种转换方法,该方法允许将指向基类的指针转换为派生类的指针。本质上,我想使用类似于if包含指向派生类的指针的东西,即.BextABdynamic_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();
}
4

2 回答 2

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

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

于 2012-06-08T09:47:50.343 回答
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..
}

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

于 2012-06-08T09:49:09.043 回答