下面的代碼正確使用Visual Studio 2013編譯:爲什麼默認移動構造函數需要unique_ptr中使用的類的default-deleter?
#include <memory>
namespace NS
{
class SomeOtherClass;
class MyClass
{
public:
MyClass();
virtual ~MyClass();
private:
std::unique_ptr<SomeOtherClass> m_someOtherClass;
};
}
int main()
{
auto mc = NS::MyClass();
}
這是因爲在Visual Studio 2013中的錯誤,其中在main
mc
初始化,直接,不檢查一個移動構造函數優化。
在Visual Studio 2015年,這並不編譯,因爲移動構造函數必須存在的,所以我們的代碼改成這樣:
#include <memory>
namespace NS
{
class SomeOtherClass;
class MyClass
{
public:
MyClass();
virtual ~MyClass();
MyClass(MyClass&&) = default;
private:
std::unique_ptr<SomeOtherClass> m_someOtherClass;
};
}
int main()
{
auto mc = NS::MyClass();
}
,這再次編譯。
但是,如果我們現在要導出DLL,那麼編譯再次失敗。這是修改後的代碼:
#include <memory>
namespace NS
{
class SomeOtherClass;
class __declspec(dllexport) MyClass
{
public:
MyClass();
virtual ~MyClass();
MyClass(MyClass&&) = default;
private:
std::unique_ptr<SomeOtherClass> m_someOtherClass;
};
}
int main()
{
auto mc = NS::MyClass();
}
這是編譯器輸出的一部分:
memory(1193): error C2027: use of undefined type 'NS::SomeOtherClass'
test.cpp(5): note: see declaration of 'NS::SomeOtherClass'
...
memory(1194): error C2338: can't delete an incomplete type
memory(1195): warning C4150: deletion of pointer to incomplete type 'NS::SomeOtherClass'; no destructor called
似乎默認生成的舉動,構造函數需要能夠破壞SomeOtherClass
。這很奇怪,因爲MyClass
有一個析構函數,其中SomeOtherClass
的完整定義是已知的。
那麼爲什麼導出DLL時不編譯?爲什麼默認的移動構造函數需要知道SomeOtherClass
的定義?
我不能告訴你爲什麼(雖然很好的問題)。你可以在你的cpp文件中有MyClass :: MyClass(MyClass &&)= default;'並且只有頭文件中的聲明時修復這個問題。 – Hayt
你不能在'main()'中寫'NS :: MyClass mc'嗎? – alain