我有一个具有相当复杂的继承结构的程序,所以我不会用它来显示我的问题,但是下面的结构使用不好的样式来使事情保持简单:

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指针与虚拟方法结合使用是行不通的。

到目前为止,我一直为派生类使用单独的 vector 或数组,因为我很少编写仅由派生类组成的程序,这些程序仅重新定义了基类的方法。

我知道我不能简单地创建一个 vector As并放入B和C而不丢失信息。

我的问题是,是否可以将As,B和C以指针或其他形式存储在单个 vector 中,并且仍然访问A中不存在的所有方法和变量?

如果不适用于 vector ,是否有替代方法(可能是数组)?

该代码可以包含现代C++(标准,std::string而不是char *等),因为不需要与C或传统C++兼容。

最佳答案

可以使用指针 vector 或更佳的 vector 来完成,这是 shared_ptr 的 vector ,方法如下:

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

原理是您将 vector (共享的)指针存储到A。因此,您可以始终访问其A::成员。

由于您的基类是多态的(即,它至少具有一个虚函数),因此可以使用dynamic_cast(对于dynamic_pointer_cast而言为 shared_ptr )尝试将指针转换为派生类的指针(例如B )。如果转换成功(非null指针),那么您就知道可以访问B::成员。

使用shared_ptr与原始指针可以简化内存管理:如果不再使用对象,则会自动删除该对象。

这里是 online demo

关于c++ - C++将派生类存储在单个 vector 中,派生类不包含重新定义的方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30513605/

10-17 00:31