在我从同事那里继承的项目中,我有带头文件和实现的基本 C++ 类。为了便于理解,我将提供示例情况,因为代码本身太大: bthidtransport.h:
class BtHidTransport
{
public:
BtHidTransport(); // constructor
protected:
virtual ~BtHidTransport(); // destructor
} // BtHidTransport
bthidtransport.cpp:
BtHidTransport::BtHidTransport
{
} // constructor
BtHidTransport::~BtHidTransport()
{
} // destructor
这是基类,现在我们有派生类头:
bthidtransportfixes.h:
#include "bthidtransport.h"
class BtHidTransportFixes : public BtHidTransport
{
BtHidTransportFixes(); // constructor
virtual ~BtHidTransportFixes(); // destructor
} // BtHidTransportFixes
但是,在特定项目中,BtHidTransportFixes 没有实现 (.cpp) 文件。项目本身构建没有错误。如果我在运行时从类实例化新对象:
BtHidTransport* createdObject=new BtHidTransportFixes();
和BtHidTransportFixes没有实现(.cpp)文件,父类的执行顺序是什么?我正在使用 Eclipse 4.3.2 for Windows(主机操作系统是 Windows 7 64bit Ultimate)和 ARM DS-5 5.20.2 编译器。项目中的任何地方都没有BtHidTransportFixes
的实现,我在所有项目文件 中搜索过它。使用 -O0 关闭编译器优化明确地标记。这是构建过程的汇编程序 list :
;;;107 // Create the BT transport first
;;;108 BtHidTransport *btTransport = new BtHidTransportFixes();
00002a 2088 MOVS r0,#0x88
00002c f7fffffe BL _ZN16StartupAllocatednwEj ; StartupAllocated::operator new(unsigned)
000030 4934 LDR r1,|L1.260|
000032 2200 MOVS r2,#0
000034 9100 STR r1,[sp,#0]
000036 4b34 LDR r3,|L1.264|
000038 4611 MOV r1,r2
00003a f7fffffe BL _ZN19BtHidTransportFixesC1EP9BtHidConnP13BtPairingListPK14tBTM_APPL_INFOPK23tBTM_LINK_EVT_CALLBACKS ; BtHidTransportFixes::BtHidTransportFixes()
00003e 4604 MOV r4,r0
和链接器输出:
Stack Usage for BtHidTransportFixes::BtHidTransportFixes() 0x0 bytes.
Stack Usage for BtHidTransportFixes::BtHidTransportFixes() 0x0 bytes.
Stack Usage for BtHidTransportFixes::BtHidTransportFixes__sub_object() unknown bytes.
BtHidTransportFixes::BtHidTransportFixes() 0x0020587d Thumb Code 0 20730_ram_ext.symdefs ABSOLUTE
BtHidTransportFixes::BtHidTransportFixes__sub_object() 0x0020587d Thumb Code 0 20730_ram_ext.symd
constructor的size好像是0,这里执行了什么exaclty?为了简化,我故意删除了构造函数的参数(此处,在问题的 StackOverflow 描述中),这是我的错吗?
最佳答案
它不必构建失败。即使在一个定义规则下隐式使用虚成员函数。
[basic.def.odr] (emphasis mine)
4 Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]). An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement.
您的工具链不必对此发出警告,也不必构建失败。它可以假装一切都很好。在那种情况下,程序显然是病式的。如果工具链设法绕过问题,或者直到发生运行时崩溃才对其进行诊断,那么这一切都在约定之内。
关于c++ - 没有实现文件 (.cpp) 的派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54549672/