【问题标题】:Adding derived class objects to vector with base interface class parameter使用基接口类参数将派生类对象添加到向量
【发布时间】:2014-04-24 23:49:19
【问题描述】:

我有一个抽象类(纯虚拟类/接口),我们将其命名为 A。

我有一个从 A 派生并实现 A 的纯虚方法的 B 类。

我有一个 C 类,其成员是指向 A 的指针向量:

std::vector<A*> myVector

还有一个方法:

add(A* item).

在从 C 派生的 D 类中,我想使用从 C 类派生的 add 方法添加 B 类的实例/对象。

我试着写成:

for(int i = 0; i < 10; i++)
{
    C::add( (A*) new B());
}

我不确定这是否符合我的要求?如果我省略 (A*) 我会收到错误:

不允许转换为不可访问的基类“A”

我是否成功地将 B 类对象指针添加到向量中?

【问题讨论】:

  • 当B 继承自A 时,您确定使用公共继承吗? (即class B : public A)
  • @unluddite:我不是,我知道这将如何导致该错误,因为基类是私有继承的。我想这不是我应该解决这个练习的方式=/

标签: c++ inheritance abstract-class abstract pure-virtual


【解决方案1】:

错误

不允许转换为不可访问的基类“A”

表示当B 派生自A 时,您没有使用公共继承。如果在指定类继承时省略了public 关键字,则默认继承是私有的(注意对于struct,默认是公共继承)。

class B : /* private */ A

应该是

class B : public A

回答你的最后一个问题:

我是否成功地将 B 类对象指针添加到向量中?

是的。

【讨论】:

  • @unluddute:那么当转换为私有基类时,它会按预期工作吗?所以错误更像是:“因为它是私有继承的,我们不知道你的基类,但是如果你转换它,我们会让你继续吗?”。我有一种感觉,首先不建议这样做,因为人们可以公开继承它并避免错误地转换它。
  • 我不是 100% 确定,但我怀疑 C 风格的演员表会使错误消失,因为它会转移到 reinterpret_cast,它允许各种疯狂的事情。在任何情况下,它都可能导致未定义的行为,因此最好避免它。
  • @Phataas:当你使用像 (A*) 这样的 C 风格强制转换时,你告诉编译器只是将内存视为存在 A 对象。编译器认为您不能在那里访问A 对象(这是一个B 对象,A 是私有的!)。但是你是老板,所以编译器按照它被告知的那样做,并将该内存视为包含A 对象所需的所有东西。在您的情况下,这似乎实际上是正确的,并且您投射的内存地址确实是 privat A 对象所在的位置。但不能保证有效,也不建议这样做。
  • @sth:谢谢你的回答。当你说它不能保证工作时,从我对类和继承的了解中,我看不出它是怎么做到的。所有基类成员和函数都首先存储在所有派生类内存占用中,因此 C 风格的基类强制转换在派生类上始终有效?
  • @Phataas:我不太确定实际保证了多少类布局,但是是的,通常它会起作用。当您添加多重继承时,它在某些情况下会中断,但通常您没有。不过,通常您不需要对基类进行显式强制转换,如果基类是私有的,那么可能是有原因的...... :)
猜你喜欢
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2014-08-30
  • 2019-02-17
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 2014-02-02
相关资源
最近更新 更多