是否调用在基类的析构函数中有虚函数是一个很好的做法?而“是否在破坏时虚函数表的存在?,并呼吁建议在析构虚函数?”什么时候在C++中破坏vtable?
回答
我可以调用基类的析构函数虚函数?
从析构函数或构造函数调用虚函数是一种不好的做法。看到标准(重点煤矿):
12.7构造和析构
....
成员函数,包括虚拟功能(10.3),可建设或破坏(12.6.2)时被调用。 当构造或销毁类的非静态数据成员期间,构造函数或析构函数直接或间接调用虚函数时,包括 ,并且调用的对象是对象(称之为x
)正在建设或销毁中,所调用的函数是构造函数或析构函数类中的最终覆盖函数 ,而不是覆盖更多派生类中的函数。如果虚拟 函数调用使用的显式类成员访问(5.2.5)和对象表达指的x
或该对象的基类的子对象中的一个,但不是x
或它的基类的子对象中的一个的完整 目的, 行为未定义。
您可以在许多来源找到这个建议,其中包括斯科特迈尔斯
有效的C++:55层具体的方法来提高你的程序以及设计 (项目9:不要调用施工或破坏时虚函数。 )
或香草萨特的
C++编码标准:101条规则,准则和最佳实践(49.避免调用虚函数的ns in constructors and destructors)。
是的,当调用析构函数时,对象将有一个指向其vtable的指针。
该标准明确表示可以在析构函数中调用虚函数,并说明会发生什么。有人认为,即使允许,这也是一个不好的做法,因为它本质上是脆弱的代码,导致显然无辜的变化带来惊喜。
如果您有从Der
DerDer
继承,从Base
继承,所有的人都覆盖成员函数void member()
,你是在Der
析构函数,并调用member()
,您呼叫Der::member()
,不DerDer::member()
,因为DerDer
你的对象的一部分已经完成,已经消失。基类可无意中指数据在派生类,例如:
struct Base {
int *ip;
Base(int *ip): ip(ip) {}
virtual void useInt() { std::cout << *ip << std::endl; }
~Base() { useInt(); }
};
struct Der: Base {
int theInt;
Der(): Base(&theInt) {}
void useIntPointer() override { std::cout << theInt << std::endl; }
};
当Der
类型的对象被删除,有“未定义的行为”:首先Der
隐式析构函数被调用,则该显式析构函数Base
,Base::~Base
。此时Base::ip
指的是已经销毁的Der
的成员。
- 1. 什么时候使用vtable?
- 2. 什么时候Android Singleton被破坏?
- 3. 什么时候OpenCV imshow()窗口被破坏? (C++)
- 4. Unity3D - 什么时候“DontDestroyOnLoad对象”被破坏?
- 5. Cookie破坏会话破坏,为什么?
- 6. 什么时候在C#中使用类?
- 7. 什么时候在C++中需要'int'?
- 8. 什么时候在C++中使用“declare”?
- 9. 什么是java中的破坏性和非破坏性方法?
- 10. C#多态 - 为什么&什么时候
- 11. 什么时候发生javascript错误会破坏代码的其余部分?
- 12. vtable中的'v'是什么?
- 13. 破译vtable转储
- 14. 什么时候使用goto * expr;在C?
- 15. 什么时候和为什么我会在C++中使用abs
- 16. 什么决定了C++程序中对象破坏的顺序?
- 17. C++破坏手册
- 18. 什么时候在C++中使用extern“C”?
- 19. 什么时候在C#中使用Properties.Settings.Default C#
- 20. 破坏不破坏
- 21. 破坏不破坏
- 22. 什么时候你把Javascript放在body里,什么时候在头,什么时候用doc.load?
- 23. 为什么在启用html5mode时这个AngularJS路由被破坏?
- 24. PHP在会话被破坏时做些什么
- 25. 为什么“display:table-cell”在“position:absolute”时被破坏
- 26. 为什么Android活动在旋转时被破坏?
- 27. 为什么NuGet在破坏项目时可以使用Microsoft.Net.Http?
- 28. 为什么WCF Stream响应在写入磁盘时被破坏?
- 29. 目标C什么时候使用alloc和什么时候不到
- 30. 什么时候我在HTML
Vtables是与类相关的静态数据结构,而不是对象。 –
发布一些代码,说明你在问什么。 –
Vtable是多态类的静态对象。但是Vtable实际上是一个指针。如果我知道这个指针何时被删除,我会很高兴。 –