C++11智能指针与多态性

12

我正在使用C++11智能指针重写一个应用程序。

我有一个基类:

class A {};

还有一个派生类:

class B : public A {
  public:
  int b;
};

我有另一个类,其中包含一个带有A或B对象的向量:

class C {
  public:
  vector<shared_ptr<A>> v;
};

我在构建C类使用A类(基类)对象时没有问题,但如何使用B类(派生类)对象填充它呢?

我正在尝试以下内容:

for(int i = 0; i < 10; i++) {
    v.push_back(make_shared<B>());
    v.back()->b = 1;
};  

编译器返回错误:

error: 类A没有名为'b'的成员


你想做什么?听起来把A视为多态是一个错误的想法,因为你不会利用它。 - R. Martinho Fernandes
3
不是智能指针的问题,你在错误地使用多态性。将公共成员b替换为虚函数(可能是get和set函数)。 - Alex F
我已经简化了类。在它们真正的形式中,多态性是有意义的。 - Medical physicist
3
那么这听起来简化的例子并不代表实际问题。 - R. Martinho Fernandes
2个回答

19

但是我该如何用 B(派生类)对象来填充它呢?

你正在用指向 B 对象的指针来填充它。然而,这些指针的静态类型指向基类 A,因此你不能直接使用它们来访问任何派生类成员。

在你的简单示例中,你可以简单地保留一个指向 B 的指针并使用它:

std::shared_ptr<B> b = make_shared<B>();
b->b = 1;
v.push_back(b);

如果您无法访问原始指针,则需要某种形式的多态:

  • 如果您知道所有对象都具有类型B,则使用 static_cast<B*>(v.back().get())
  • 如果对象可能具有不同的类型,则使用虚函数或dynamic_cast(后者需要基类包含虚函数才能工作)

5
for(int i = 0; i < 10; i++) {
    auto bptr = make_shared<B>();
    v.push_back(bptr);
    bptr->b = 1;
};  

5
谢谢您的回答。它是正确的,但是Mike Seymour的解释帮助我理解了为什么。 - Medical physicist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接