'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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:maze
下一篇:strcpy的内联实现

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年05月04日 20时57分36秒