没有实现文件(.cpp)的派生类

时间:2019-02-06 08:50:33

标签: c++ oop arm cross-compiling

在我从同事那里继承的项目中,我有带有头和实现的基本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标志明确地关闭编译器优化。这是构建过程的汇编程序清单:

;;;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

构造函数的大小似乎为0,在这里执行什么技巧?为了简化起见,我特意删除了构造函数的参数(在此处,在问题的StackOverflow中),这是我的不好吗?

3 个答案:

答案 0 :(得分:6)

它不必构建失败。即使在一个定义规则下隐式使用了虚拟成员函数。

  

[basic.def.odr] (强调我的意思)

     

4每个程序应仅包含每个程序的一个定义   该程序中使用的非内联函数或变量   在被遗弃的声明之外; 无需诊断。的   定义可以显式出现在程序中,可以在   标准库或用户定义的库,或者(如果适用)   隐式定义(请参见[class.ctor],[class.dtor]和[class.copy])。   内联函数或变量应在每次翻译中定义   在废弃的语句外使用的单位。

您的工具链不必对其进行警告或构建失败。它可以假装一切都很好。在这种情况下,该程序格式不正确。如果工具链设法解决问题,或者直到运行时崩溃发生时才诊断出问题,那么一切就在合同之内。

答案 1 :(得分:2)

如果程序缺少声明的成员函数的实现,则根本无法执行-链接器将无法生成可执行文件。

缺少实现无关紧要的唯一事情就是是否从未使用相应的类。在这种情况下,链接程序将永远不会被迫寻找实现。

但是,如果您的程序包含-如您所说-下一行

DerivedClass* derivedClass=new DerivedClass();

程序格式错误(链接器应该抱怨)。

答案 2 :(得分:0)

我找到了解决特定问题的方法。指示生成过程文件( .inc )用修补的 bthidtransportfixes.h 替换头文件 bthidtransportfixes.h ,该文件未包含在项目树中本身,但是驻留在 Windows用户主目录中,然后将缺少的代码本身从修补的标头复制到原始内容。如果我清理项目,则操作相反。真是胡说八道,这个项目被搞砸了!这是缺少的构造函数代码,摘自补丁:

BtHidTransportFixes::BtHidTransportFixes(BtHidConn            *btHidConn, 
                                         BtPairingList        *hostList, 
                                         const tBTM_APPL_INFO *btmSecCallbacks,
                                         const tBTM_LINK_EVT_CALLBACKS *btmLinkEvtCb) :
    BtHidTransport(btHidConn, hostList, btmSecCallbacks, btmLinkEvtCb)
{
    #ifdef PROXIMITY_ASSOCIATION_SUPPORT
        // Initialize the observer to NULL
        proxAssocObserver.pObj = NULL;
    #endif
    #ifdef FIX_NEED_DISCOVERYLED_TICK
        discoveryTickEnabled = hidAppConfig.discoveryLedEnabled;

        discoveryTickBasePeriodInMs = 50;
    #endif

    #ifdef FIX_CQ_911035
        ucdConnectRequested = FALSE;
    #endif
}

我自己创建了实现文件,将其添加到项目中,将修补的代码放入其中,删除 .inc 命令以包含补丁,添加了新的实现文件以构建过程,现在它像魅力。