【问题标题】:C++ - Reach derived class variables from vectorC++ - 从向量中获取派生类变量
【发布时间】:2012-11-26 17:08:00
【问题描述】:

我真的很困惑,所以我不得不问这个。我尝试编写一个应用程序,但我不知道如何访问派生类的变量,这些变量位于基类的向量中。 代码是:

class A {
public:
    A() { };

    std::vector<A> aVector;

    void Foo();
}

class B : public A {
public:
    B() { };

    int j;
}

void A::Foo() {
    aVector.push_back( B() );

    // Here I would like to reach B::j, but only the members and variables of A comes in
    aVector[0].j; // wrong
    B b = aVector[0];   // no suitable user-defined conversion from "A" to "B" exists
                        // should I use cast? which one?
}

我目前正在通过应用程序编程学习继承和这类东西,现在我真的卡住了。

我查找了其他问题,但找不到任何可以解决我的问题的问题。如果有,我错过了,对不起。

【问题讨论】:

    标签: c++ inheritance vector


    【解决方案1】:

    您需要将pointers 存储到A,这样您的新B 对象在推入向量时不会被“切片”(参见说明here)。

    另外,当您想在基类的指针上专门使用子方法/变量时,您需要将cast 转换为正确的类型

    std::vector<A*> aVector;
    aVector.push_back(new B());
    B* b = (B*)aVector[0];
    cout << b->j;
    // remember to delete the content of aVector
    

    如果您不能 100% 确定它是您要投射的类型,那么投射这样的对象可能会很危险。

    请参阅this thread 了解更多关于选角的信息(C styledynamic_caststatic_cast

    【讨论】:

    • 理想情况下,您应该存储 smart 指向A 的指针。想象一个裸向量,里面有数百万个指针,突然发生异常。 :P
    • 虽然我同意,但我认为我们正在远离最初的问题 :)
    • 谢谢!我接受了这一点,因为这给了我一个可行的解决方案。但是现在我看到还有很多东西要学:)
    【解决方案2】:

    由于vector 被声明为包含A 类型的对象,因此当您将B 推入向量时,所有B-ness 都会从存储在@987654326 中的对象中剥离@。这被称为slicing problem

    当您稍后尝试访问存储在vector 中的对象的B 元素时,您无法访问,因为它们根本不存在。您没有 vector 的 B 个对象 - 您有 vectorA 对象。

    为了解决这个问题,你需要存储A对象,而不是通过值,而是通过引用或指针。您不能将引用存储在 vector 中,所以这会给您留下指针。

    【讨论】:

      【解决方案3】:

      这与向量无关。如果B 派生自A,则以下代码:

      A a;
      B b = a;
      

      是一个错误(除非有某种方法可以转换)。

      这是正确的 - 您应该能够统一处理您的矢量项目。如果这意味着使用向量的代码期望所有项目都是B,那么只需创建一个vector&lt;B&gt;。如果不是,那么无论如何您都没有将A 转换为B 的业务。

      【讨论】:

        【解决方案4】:

        您不应该尝试从基类访问派生类成员。基类应该不知道派生类的实现细节。你正在做的不是多态的。换句话说,您的 B 实例不能像 A 实例那样运行,因为您没有提供任何虚拟方法并且没有覆盖任何虚拟方法。

        整个设计和方法不正确。 A::Foo() 应该是一个虚拟方法(甚至可能是抽象的)。你应该在 B::Foo() 中工作。

        还有一件事,你不应该只持有一个简单的旧 A 的向量。它应该是指向 A 的指针。所以 std::Vector。并且该成员应该以字母 m 为前缀,以表明它是该类的成员变量。所以 std::vector mSomething;

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-10-11
          • 2011-07-13
          • 2013-11-18
          • 2018-12-24
          • 2013-03-28
          • 2016-03-30
          • 1970-01-01
          相关资源
          最近更新 更多