我有一组类似于下面显示的类。但是,我想允许用户从它们派生,而不必使用其他虚拟方法修改基类。有没有办法修改代码而不必在类 A
中声明virtual int GetT(void){return 0;};
?
为了进一步解释这个问题,我想允许用户使用自己的方法扩展A
和B
(或Aext
和Bext
),这些方法在A
和B
中未定义为虚拟方法。我正在寻找一种强制转换方法,该方法允许将指向基类的指针转换为派生类的指针。从本质上讲,如果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..
}
我不确定这是你正在寻找的答案;希望这有帮助,无论如何。