我有一个可以响应A
的类doSomething()
和一些子类B
,C
和D
,它们都覆盖了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]
访问它。注意:在编译器中禁用此“扩展名”是一个好主意,以避免遇到此类问题。