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