'inline' is the only legal storage class for constructors
发布日期:2021-06-30 22:10:24
浏览次数:2
分类:技术文章
本文共 3099 字,大约阅读时间需要 10 分钟。
前言
如果构造函数前面加上虚函数修饰,就会报错:
‘inline’ is the only legal storage class for constructors记录
// Obj5.h: interface for the CObj5 class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_OBJ5_H__30083DAA_0A5D_49B7_B757_F572167873B1__INCLUDED_)#define AFX_OBJ5_H__30083DAA_0A5D_49B7_B757_F572167873B1__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include#include "Obj4.h"class CObj5 : public CObj4{public: /** c++语法不允许构造函数为虚函数 'inline' is the only legal storage class for constructors “内联”是构造函数的唯一合法存储类 */ /*virtual*/ CObj5(); virtual ~CObj5(); void test();private: DWORD m_dwID;};#endif // !defined(AFX_OBJ5_H__30083DAA_0A5D_49B7_B757_F572167873B1__INCLUDED_)
// Obj5.cpp: implementation of the CObj5 class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "Obj5.h"//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CObj5::CObj5():m_dwID(-1){}CObj5::~CObj5(){}void CObj5::test() { printf("void CObj5::test()\r\n");}
报错的原因
- c++语法不支持构造函数为虚, 编译不过
- 从构造函数运行原理上说,也可以有佐证. 当一个类进入构造函数后,首先会调用基类构造函数,再执行本类初始化列表,最后调用本类的构造函数。 从构造函数反汇编代码可以看到
12: CObj5::CObj5()13: :m_dwID(-1)14: {00401160 55 push ebp00401161 8B EC mov ebp,esp00401163 83 EC 44 sub esp,44h00401166 53 push ebx00401167 56 push esi00401168 57 push edi00401169 51 push ecx0040116A 8D 7D BC lea edi,[ebp-44h]0040116D B9 11 00 00 00 mov ecx,11h00401172 B8 CC CC CC CC mov eax,0CCCCCCCCh00401177 F3 AB rep stos dword ptr [edi]00401179 59 pop ecx0040117A 89 4D FC mov dword ptr [ebp-4],ecx0040117D 8B 4D FC mov ecx,dword ptr [ebp-4]00401180 E8 A3 FE FF FF call @ILT+35(CObj4::CObj4) (00401028)00401185 8B 45 FC mov eax,dword ptr [ebp-4]00401188 C7 40 04 FF FF FF FF mov dword ptr [eax+4],0FFFFFFFFh0040118F 8B 4D FC mov ecx,dword ptr [ebp-4]00401192 C7 01 20 70 42 00 mov dword ptr [ecx],offset CObj5::`vftable' (00427020)15:16: }00401198 8B 45 FC mov eax,dword ptr [ebp-4]0040119B 5F pop edi0040119C 5E pop esi0040119D 5B pop ebx0040119E 83 C4 44 add esp,44h004011A1 3B EC cmp ebp,esp004011A3 E8 68 02 00 00 call __chkesp (00401410)004011A8 8B E5 mov esp,ebp004011AA 5D pop ebp004011AB C3 ret
- 根据构造函数运行原理, 假设编译器允许构造函数为虚。会导致以下问题: 当子类执行构造之前,会先去执行父类构造,但是因为子类构造为虚,执行的父类构造是子类构造。 父类构造函数没有机会执行了. 实际情况就为子类的构造会执行2次。 而不是先执行父类构造一次,再执行子类构造一次.
总结
当构造函数为虚函数时, 编译器报错是合理的.
如果编译器不报错,程序运行时的结果不符合类构造函数运行原理,会导致更隐蔽的BUG.转载地址:https://lostspeed.blog.csdn.net/article/details/52529184 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
关注你微信了!
[***.104.42.241]2024年05月04日 20时57分36秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
推荐系统初学
2019-05-01
Map的遍历和排序
2019-05-01
约瑟夫环问题
2019-05-01
springboot+log4j2体验
2019-05-01
redis集群启动方式
2019-05-01
ubuntu系统开机自启动方式
2019-05-01
ES查询效率之快的三个重要技术
2019-05-01
JDBC概念,JDBC连接到Oracle 11g(内附驱动jar包),
2019-05-01
彻底卸载MySQL
2019-05-01
Oracle创建表,修改表(添加列、修改列、删除列、修改表的名称以及修改列名)
2019-05-01
SQL命令分类(DDL、DML、DCL、TCL以及事务)
2019-05-01
nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate 报错
2019-05-01
kafka集群搭建
2019-05-01
Python正则表达式,从入门到实战,精华都在这里!
2019-05-01
喜欢玩王者荣耀的有福了,用 Python 获取英雄皮肤壁纸
2019-05-01
一名数据分析师的SQL学习历程
2019-05-01
图解《金字塔原理》,7步掌握其精华!
2019-05-01
数据分析入门选择Python还是SQL?七个常用操作对比!
2019-05-01
最后一台,i7+6核电脑
2019-05-01
19款国产手机无一幸免:15分钟破解人脸识别,打印眼镜让刷脸形同虚设
2019-05-01