我一直在嘗試通過使用 unique_ptr 來實作 PIMPL 習語。我從幾篇文章中得到啟發,這些文章總是強調同樣的重點:只在實作 PIMPL 的類的頭檔案中宣告解構式,然后在你的 .cpp 檔案中定義它。否則,你會得到像“Incomplete type bla bla”這樣的編譯錯誤。
好吧,我做了一個尊重這一點的小測驗,但我仍然有“不完整型別”錯誤。代碼就在下面,很短。
A.hpp:
#pragma once
#include <memory>
class A
{
public:
A();
~A();
private:
class B;
std::unique_ptr<B> m_b = nullptr;
};
A.cpp:
#include "A.hpp"
class A::B
{
};
A::A()
{
}
A::~A() // could be also '= default'
{
}
主.cpp:
#include "A.hpp"
int main()
{
A a1;
return 0;
}
我以 2(快速和骯臟)的方式構建,從我的角度來看,結果非常令人驚訝。
首先我在沒有鏈接 A.cpp 的情況下構建
g -c A.cpp
到目前為止沒有錯誤。
然后,我編譯了 A.cpp 和 main.cpp 來創建一個可執行檔案
g A.cpp main.cpp -o test
這就是我遇到麻煩的地方。在這里,我得到了關于不完整型別的著名錯誤:
In file included from /usr/include/c /9/memory:80,
from A.hpp:2,
from test.cpp:2:
/usr/include/c /9/bits/unique_ptr.h: In instantiation of ‘void std::default_delete<_Tp>::operator()(_Tp*) const [with _Tp = A::B]’:
/usr/include/c /9/bits/unique_ptr.h:292:17: required from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = A::B; _Dp = std::default_delete<A::B>]’
A.hpp:11:28: required from here
/usr/include/c /9/bits/unique_ptr.h:79:16: error: invalid application of ‘sizeof’ to incomplete type ‘A::B’
79 | static_assert(sizeof(_Tp)>0,
| ^~~~~~~~~~~
I know what the constraints are when you intend to use unique_ptr as a part the PIMPL idiom and I tried to care about them. However, in this case, I have to admit that I'm out of idea (and hairs as it gets me on my nerves).
Do I do something wrong, or are we just not censed to use unique_ptr in such a case ?
Live demo
uj5u.com熱心網友回復:
我(還)不完全理解這個問題,但原因是成員的默認成員初始化程式m_ptr。如果您使用成員初始化器串列,它編譯時不會出錯:
// A.hpp:
class A
{
public:
A();
~A();
private:
class B;
std::unique_ptr<B> m_b; // no initializer here
};
// A.cpp:
A::A() : m_b(nullptr) // initializer here
{
}
https://wandbox.org/permlink/R6SXqov0nl7okAW0
請注意,clangs 錯誤訊息更適合指向導致錯誤的行:
In file included from prog.cc:1:
In file included from ./A.hpp:3:
In file included from /opt/wandbox/clang-13.0.0/include/c /v1/memory:682:
In file included from /opt/wandbox/clang-13.0.0/include/c /v1/__memory/shared_ptr.h:25:
/opt/wandbox/clang-13.0.0/include/c /v1/__memory/unique_ptr.h:53:19: error: invalid application of 'sizeof' to an incomplete type 'A::B'
static_assert(sizeof(_Tp) > 0,
^~~~~~~~~~~
/opt/wandbox/clang-13.0.0/include/c /v1/__memory/unique_ptr.h:318:7: note: in instantiation of member function 'std::default_delete<A::B>::operator()' requested here
__ptr_.second()(__tmp);
^
/opt/wandbox/clang-13.0.0/include/c /v1/__memory/unique_ptr.h:272:19: note: in instantiation of member function 'std::unique_ptr<A::B>::reset' requested here
~unique_ptr() { reset(); }
^
./A.hpp:12:28: note: in instantiation of member function 'std::unique_ptr<A::B>::~unique_ptr' requested here
std::unique_ptr<B> m_b = nullptr;
^
./A.hpp:11:9: note: forward declaration of 'A::B'
class B;
^
1 error generated.
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/440075.html
上一篇:為什么我的SDL2代碼不顯示帶有SDL_Texture*的影像
下一篇:指標陣列引起的記憶體泄漏?
