簡體   English   中英

在類主體外部定義的C ++成員函數的編譯

[英]Compilation of C++ member functions defined outside the class body

我有一個這樣的hpp文件:

#ifndef __MYLIB_H
#define __MYLIB_H

class A {
public:
  void func1();
  void func2();  
};

void A::func1() {
  // maybe do something
}

#endif

有一個相應的cpp文件,該文件具有func2的實現。 頭文件包含在項目中的其他文件中(而頭文件包含在更多文件中)。 當我嘗試構建它時,我收到func1 “多個定義”鏈接器錯誤。 為什么會這樣? 由於我已經使用#ifndef保護了頭文件,所以我沒想到會出現該錯誤。

如果我將關鍵字inline添加到func1的定義中,那么一切都很好。 因此,如果我不關心要內聯的函數並且不想在類主體中包含定義,則無法在hpp文件中包含該定義? 如果有人可以解釋這里發生的事情,那將非常有幫助。 我正在使用GCC 6。

問題是您要在每個文件中重新定義func1

#include指令是一個非常簡單的命令,它僅將頭文件的內容粘貼到指定的位置。

這樣的結果是,每次#include您的標頭時,您都在該文件中“重新定義” func1

回想一下,整個標頭的內容以及它可能包含的任何文件,實際上都是“復制粘貼”到每個包含翻譯頭中的標頭的翻譯單元 *中。

這就是為什么將標頭包含在多個CPP文件中的效果與您將字面意義上的復制的函數定義逐字復制到每個CPP中的原因相同,即,就像您為同一成員函數編寫了多個相同的定義一樣。

通過聲明inline函數可以解決該問題,因為C ++允許內聯函數的多個定義,只要它們彼此相同即可。 將函數的主體移到類的聲明中也是可行的,因為此類函數會自動視為inline

*在這種情況下,“翻譯單位”是CPP文件的花哨名稱。

通常,實現在關聯的.cpp文件中。 將它們放在標題中是有問題的。 inline是一種可以避免這種情況的黑客,您可能不想使用它,因為它會在代碼出現的任何地方都將其標記出來,從而導致大量重復。

請記住, #include就像將該文件粘貼到該指令出現的代碼中一樣。 一個函數有多個實現是不正確的,這就是為什么出於簽名目的而將它們划分在標頭之間的原因,因此可以理解如何正確使用這些函數以及實際代碼的實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM