【问题标题】:Calling method of child class on a vector of parent class在父类的向量上调用子类的方法
【发布时间】:2011-09-05 23:40:25
【问题描述】:
#include <iostream>
#include <vector>

using namespace std;

class Parent {
public:
    Parent();
    void method();
};

class Child: public Parent {
public:
    Child();
    void method();
};

int main() {
    vector<Parent> v;
    v.push_back(Parent());
    v.push_back(Child());
    v[0].method();
    v[1].method();
    return 0;
}

Parent::Parent() {}

void Parent::method() {
    cout << "Parent." << endl;
}

Child::Child() {}

void Child::method() {
    cout << "Child." << endl;
}

基本上我希望该程序能够打印

Parent.
Child.

但它会打印出来:

Parent.
Parent.

C++ 再次让我感到惊讶 :)。
为什么会这样?对于向量中的 Child 实例调用 Child::method 并为 Parent 实例调用 Parent::method 该怎么做?

我正在使用 gcc:

gcc version 4.6.1 20110819 (prerelease) (GCC)

像这样:

g++ -Wall -Wextra -c main.cpp
g++ -Wall -Wextra -o main main.o

【问题讨论】:

  • @Tomalak:我搜索过。很多。但是我怎么知道这叫做“切片”呢? ://
  • 搜索parent child vector c++ 可能会做到这一点。
  • @Tomalak:嗯,我不认为这是一个普遍的问题,也许认为这有点牵强。但是点了,我的错。

标签: c++ oop vector polymorphism stdvector


【解决方案1】:

您遇到了切片问题

vector&lt;Parent&gt;.push_back() 复制它的参数,所以它调用Parent::Parent(const Parent &amp;)(即复制构造函数)*

这真的和:

Parent x[10];

x[0] = Parent();
x[1] = Child();

* 或者它可能是Parent::operator=(const Parent &amp;),即复制分配。我累了,不记得需要哪个了。

【讨论】:

  • @Oli:我认为它实际上并没有被指定。复制构造需要放置新的;复制分配需要初始默认构造。所以我想说一个理智的实现通常会做前者。
  • n3290: 23.2.1/13 描述了CopyInsertableness,这是唯一的要求。它说默认分配器将使用放置new,但其他人可能不会。
【解决方案2】:

向量存储Parents,而不是Childrens。

如果您想利用多态性,请改为存储指针...但该死的确定这是您想要的。

【讨论】:

  • 这还不能真正解决问题,因为method 不是virtual
  • @pmr:确实,还有更多工作要做。但是,我写答案的目的并不是为了让它成为一本 25 页的关于多态性的书籍章节。 OP 可以在他自己的书中查找该章节的完整故事。
  • @Gerardo 这就是我一直在说的。您的成员函数必须是virtual。托马拉克当然是对的:你需要读一本书。
  • 感谢 Tomalak 和 @pmr,这帮了大忙。
猜你喜欢
  • 2023-02-26
  • 2016-02-14
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 2017-11-09
  • 2012-10-28
  • 2012-02-22
相关资源
最近更新 更多