我有一个可以响应A的类doSomething()和一些子类BCD,它们都覆盖了doSomething()B特别具有一个实例变量,该实例变量是标准库中的列表,并在响应doSomething()时将元素添加到该列表中。

在我的代码的某些部分中,我创建了一个数组,其中包含指向A类型的对象的指针。现在,如果我这样声明:

A* pointersToA[3];
pointersToA[0] = &B();
pointersToA[1] = &C();
pointersToA[2] = &D();


呼叫List insert iterator outside range时得到pointersToA[0]->doSomething()

但是,如果我这样做:

A* pointersToA[3];
B b = B();
pointersToA[0] = &b;
pointersToA[1] = &C();
pointersToA[2] = &D();


一切正常。

为什么会这样?

最佳答案

执行此操作时:

pointersToA[0] = &B();


您正在pointersToA[0]中存储指向临时文件的指针。这在标准C ++中是无效的,并且一致的实现应发出错误。这个适合您的编译器的事实表明您的编译器具有错误或非标准扩展。

假设您的编译器接受该代码,问题在于在该行之后,pointersToA[0]无效,因为它指向的B对象不再存在。取消引用该指针是未定义的行为。

当你这样做

B b = B();
pointersToA[0] = &b;


您存储一个指向对象b的指针。只要b仍然存在,就可以通过pointersToA[0]访问它。



注意:在编译器中禁用此“扩展名”是一个好主意,以避免遇到此类问题。

10-08 14:35