2016-09-18 35 views
-1

我有下面的類(非真名):默認nullptr指針類構造函數得到解析外部符號C++

class CObject1 : public IObject1 
{ 
public: 
    CObject1(IObject2 *pIObject2 = nullptr); 
} 

其中「I」版本的接口類。現在,當我創建CObject1的實例爲:

CObject1 object1; 

我得到一個未解決的外部符號,抱怨CObject1(無效)未找到。如果我嘗試顯式聲明另一個構造函數爲:

CObject1() 

我那麼顯然得到了「指定多個默認構造函數」的警告,正如人們所期望的那樣。

爲什麼程序找不到我的默認ctor?

在此先感謝。

編輯: 其他注意事項:

  • 接口本身不具有構造函數明確定義。
  • 所有這些都在相同的命名空間下。即接口定義,實現和實例化。
  • 我在MS單元測試中看到了這個。我沒有一個可以測試的「正常」項目。
+0

那麼,其中*是你的構造函數的實現嗎?另外,請注意,您的定義適用於需要參數的構造函數。調用者負責填充該參數。有沒有可能你有代碼的地方實際上預計會有一個默認的ctor? – kfsone

+0

無法用clang再現http://coliru.stacked-crooked.com/a/8f593e56ee403f20,gcc http://coliru.stacked-crooked.com/a/866ce558d29ee66e或msvc http://rextester.com/ODLZ30170 – kfsone

+0

該實現在其cpp文件中。真的沒什麼特別的。 – ThermoX

回答

1

您的課程不是生成默認構造函數(CObject1())。它產生的是一個構造函數,它需要一個參數,任何讀取該定義的代碼都會知道如果它遇到本來是默認ctor的參數 - 這是在調用站點完成的。

class C { 
public: 
    C(int* p = nullptr); 
}; 

C fn() { 
    C c{}; 
    return c; 
}; 

Generates

fn():         # @fn() 
     pushq %rax 
     leaq (%rsp), %rdi 
     xorl %esi, %esi ; <<- injects the nullptr 
     callq C::C(int*) ; <<- note which ctor is called 
     popq %rax 
     retq 

但是:單元測試框架可能不會看到該定義,並與你的對象有一個默認的構造函數的要求工作。在這種情況下,你應該考慮寫作:

CObject1() : CObject1(nullptr) {} 
CObject1(IObject2 *pIObject2); 
+0

我需要破譯這個...但我只是在上面指出,在一個評論中,當我用相同的實例創建一個空的控制檯應用程序...它編譯得很好。所以你的結論聽起來不錯我只需要充分理解現在的原因:)謝謝。 – ThermoX

+0

btw kfsone,我想到了創建2顯式構造並忘記= nullptr版本。但是這對我來說有點令人不安,因爲我在ctor中使用了其他一些默認值,這意味着我必須修改所有這些,以防萬一。沒有太大的交易,只是令人不安,因爲我真的沒有想到這種行爲 - 全部。但我不是專家。 – ThermoX

+0

好吧......現在不是凌晨1點...我明白你的答案。我假設這種行爲並不是獨特的。它讓我擔心有些情況下程序可能看不到具有默認值參數的函數,然後無法編譯。 (也......不知道爲什麼有人對我的問題投了棄權票,而不是解釋爲什麼。) – ThermoX

相關問題