[英]derived class with no implementation file (.cpp)
在我從同事那里繼承的項目中,我有帶有標題和實現的基本 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,這里執行的是什么exaclty? 為了簡化,我故意刪除了構造函數的參數(這里,在 StackOverflow 的問題描述中),這是我的錯嗎?
它不必失敗。 即使在一個定義規則下隱式使用虛擬成員函數。
[basic.def.odr] (強調我的)
4每個程序都應包含在該程序中被 odr 在丟棄語句之外使用的每個非內聯函數或變量的一個定義; 無需診斷。 定義可以顯式地出現在程序中,可以在標准或用戶定義的庫中找到,或者(在適當的時候)它是隱式定義的(參見 [class.ctor]、[class.dtor] 和 [class.copy] ])。 內聯函數或變量應在每個翻譯單元中定義,其中它在被丟棄的語句之外被 odr 使用。
您的工具鏈不必對此發出警告,也不必構建失敗。 它可以假裝一切都很好。 在這種情況下,程序顯然是格式錯誤的。 如果工具鏈設法解決問題,或者直到運行時崩潰發生才對其進行診斷,這一切都在合同之內。
如果程序缺少聲明成員函數的實現,則根本無法執行 - 鏈接器將無法構建可執行文件。
唯一缺少實現無關緊要的是,是否從未使用過相應的類。 在這種情況下,鏈接器永遠不會被迫尋找實現。
但是,如果您的程序包含 - 正如您所說的 - 以下行
DerivedClass* derivedClass=new DerivedClass();
程序格式錯誤(鏈接器應該抱怨)。
我找到了解決特定問題的方法。 指示構建過程文件 ( .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命令以包含補丁,添加新的實現文件以構建過程,現在它就像一個魅力。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.