使用类的编译器的行为

时间:2012-06-18 03:24:32

标签: c++ class inheritance types

#include <list>
using std::list;
class foo { ...
class bar : public foo { ...
static void print_all(list<foo*> &L) { ...
list<foo*> LF;
list<bar*> LB;
...
print_all(LF); // works fine
print_all(LB); // static semantic error

我想我知道为什么编译器不允许第二次调用。任何人都可以举例说明如果编译器接受这种调用可能会发生的坏事吗?

2 个答案:

答案 0 :(得分:3)

当然!如果print_all这样做会怎么样:

L.push_back(new Foo);

现在,您的Bar指针列表中有一个指向不是Bar的Foo对象的指针。如果然后尝试调用Foo类中不存在的Bar中的方法,则会遇到某种严重的运行时问题,因为该方法在Foo对象中不存在。

希望这有帮助!

答案 1 :(得分:2)

代码中有两个不同的东西,有不同的解释。第一个问题是模板的不同实例化是不相关的,即使实例化类型是相关的。在此特定情况下,std::list<foo*>std::list<bar*>无关,即使foobar的基础。这是语言设计的一部分,没有什么可以做的。

第二个问题,不是编译器抱怨的问题,一般来说,derived的容器不能被引用用作base的容器。这就是@templatetypedef带来的问题 - 但同样,这不是代码中的问题,它将是一个不同的例子:

void f( base** p );
int main() {
   derived *d;
   f( &d );          // error
}

在这种情况下,问题是,因为@templatetypedef指出使用derived的指针/容器代替非const中的base 指针/容器方式容易出错,因为你可以在指针/容器上存储非derived类型。