C++ 将派生 类 存储在单个向量中,派生 类 不包含重新定义的方法
C++ storing derived classes in a single vector with the derived classes not containg redifined methods
我有一个继承结构相当复杂的程序,所以我不会用它来说明我的问题,但下面的结构使用糟糕的风格来使事情简单化:
class A {
public:
int va1;
int va2;
string va3;
virtual void fa1(int x1, string x2) {
// method body
}
int fa2 (bool y1, double y2) {
// method body
}
A() {
}
virtual ~A() {
}
};
class B :
public A
{
public:
bool ab1;
double ab2;
long double ab3;
bool fb1(double x1) {
//method body
}
long double fb2() {
//method body
}
B(int z1) {
ab2 = z1;
}
virtual ~B() {
}
};
class C :
public A
{
public:
int ac1;
long double fc1() {
//method body
}
virtual void fa1(int x1, string x2) {
// method body
}
C() {
}
virtual ~C() {
}
};
如您所见,B 和 C 主要由全新的变量和方法组成,而不是从 A 中重新定义的变量和方法。
因此,将 A 指针与虚方法结合使用是行不通的。
直到现在,我一直对派生 类 使用单独的向量或数组,因为我很少编写主要由派生 类 组成的程序,这些程序只重新定义基本 类' 方法。
我知道我不能简单地创建一个 A 向量并放入 B 和 C 而不丢失信息。
我的问题是,是否可以将 As、Bs 和 Cs 以指针或其他形式存储在单个向量中,并且仍然可以访问 A 中不存在的所有方法和变量?
如果它不适用于向量,是否有替代方案(也许是数组)?
代码可以包含现代 C++(标准,std::string 而不是 char* 等),因为不需要与 C 或传统 C++ 兼容。
这可以使用指针向量或更好的向量来完成,shared_ptr
这样的向量:
vector<shared_ptr<A>> v; // vector of shared ponters to A
v.push_back(make_shared<A>());
v.push_back(make_shared<B>(2));
v.push_back(make_shared<C>());
shared_ptr<A> pa = v[1]; // this one is a B but in real life we would'nt know
// I can use all the A methods without question
shared_ptr<B> pb = dynamic_pointer_cast<B>(pa); // attempt to cast it to a B
if (pb) { // if casting succeded
pb->fb2(); // I call the B method
} else cout << "Not a B"<<endl; // if not, I know that it's an A but not a B
原则是您将指向 A 的向量(共享)指针存储在其中。因此您始终可以访问其 A::
成员。
因为你的基础class是多态的(即它至少有一个虚函数),dynamic_cast
(dynamic_pointer_cast
在shared_ptr
) 的情况可用于尝试将指针转换为派生 class 的指针(例如 B)。如果转换成功(非空指针),您就知道可以访问 B::
成员。
使用 shared_ptr 与原始指针相比,有助于内存管理:如果不再使用某个对象,它会自动删除。
这里是online demo.
我有一个继承结构相当复杂的程序,所以我不会用它来说明我的问题,但下面的结构使用糟糕的风格来使事情简单化:
class A {
public:
int va1;
int va2;
string va3;
virtual void fa1(int x1, string x2) {
// method body
}
int fa2 (bool y1, double y2) {
// method body
}
A() {
}
virtual ~A() {
}
};
class B :
public A
{
public:
bool ab1;
double ab2;
long double ab3;
bool fb1(double x1) {
//method body
}
long double fb2() {
//method body
}
B(int z1) {
ab2 = z1;
}
virtual ~B() {
}
};
class C :
public A
{
public:
int ac1;
long double fc1() {
//method body
}
virtual void fa1(int x1, string x2) {
// method body
}
C() {
}
virtual ~C() {
}
};
如您所见,B 和 C 主要由全新的变量和方法组成,而不是从 A 中重新定义的变量和方法。 因此,将 A 指针与虚方法结合使用是行不通的。
直到现在,我一直对派生 类 使用单独的向量或数组,因为我很少编写主要由派生 类 组成的程序,这些程序只重新定义基本 类' 方法。
我知道我不能简单地创建一个 A 向量并放入 B 和 C 而不丢失信息。
我的问题是,是否可以将 As、Bs 和 Cs 以指针或其他形式存储在单个向量中,并且仍然可以访问 A 中不存在的所有方法和变量?
如果它不适用于向量,是否有替代方案(也许是数组)?
代码可以包含现代 C++(标准,std::string 而不是 char* 等),因为不需要与 C 或传统 C++ 兼容。
这可以使用指针向量或更好的向量来完成,shared_ptr
这样的向量:
vector<shared_ptr<A>> v; // vector of shared ponters to A
v.push_back(make_shared<A>());
v.push_back(make_shared<B>(2));
v.push_back(make_shared<C>());
shared_ptr<A> pa = v[1]; // this one is a B but in real life we would'nt know
// I can use all the A methods without question
shared_ptr<B> pb = dynamic_pointer_cast<B>(pa); // attempt to cast it to a B
if (pb) { // if casting succeded
pb->fb2(); // I call the B method
} else cout << "Not a B"<<endl; // if not, I know that it's an A but not a B
原则是您将指向 A 的向量(共享)指针存储在其中。因此您始终可以访问其 A::
成员。
因为你的基础class是多态的(即它至少有一个虚函数),dynamic_cast
(dynamic_pointer_cast
在shared_ptr
) 的情况可用于尝试将指针转换为派生 class 的指针(例如 B)。如果转换成功(非空指针),您就知道可以访问 B::
成员。
使用 shared_ptr 与原始指针相比,有助于内存管理:如果不再使用某个对象,它会自动删除。
这里是online demo.