我已经查看了许多关于 pImpl、unique_ptr 和前向声明的 SO 问题,但无法找出问题所在。答案是std::unique_ptr<T> 需要知道 T 的完整定义吗?看起来很完整,但我不知道如何将其应用到我的情况。
我在https://wandbox.org/permlink/9joq3PnkEZ6j8TI8有一个简单的 pImpl 模式。主类包含 impl 类的 unique_ptr,它管理一些资源,因此它具有自定义构造函数/析构函数。我正在使用带有 clang 14 的 C++20(在 MacOS 上,确实如此,但在上面的 wandbox 中也发生了同样的错误)。
编译它会出现可怕的“对不完整类型无效应用‘sizeof’”错误。
代码是这样的:
// testclass.h
#include <experimental/propagate_const>
// Main class with a pImpl pattern -- impl class is incomplete here.
class Main {
public:
void main_f();
Main();
private:
class impl;
std::experimental::propagate_const<std::unique_ptr<impl>> pImpl;
};
Run Code Online (Sandbox Code Playgroud)
// testclass.cpp
#include "testclass.h"
// Implementation of Main with its impl
class Main::impl {
private:
int foo;
public:
impl() = default;
~impl() {
cout << "bye from impl";
};
impl(const impl &) = delete;
impl &operator=(const impl &other) = delete;
impl(impl &&source) noexcept = default;
impl &operator=(impl &&other) noexcept = default;
}
// To construct a Main, construct a unique pointer to a new impl
Main::Main() : pImpl{std::make_unique<impl>()} {}
Run Code Online (Sandbox Code Playgroud)
和主要:
// main.cpp
#include "testclass.h"
int main() {
Main main;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有人能指出我正确的方向吗?
您需要~Main();在类中声明析构函数,并在 .cpp 文件中定义它。
那是因为它的定义需要impl完整,而现在它在创建时被隐式定义Main main;,并且impl不完整。
您可能希望对移动操作执行相同的操作,因为由于自定义析构函数,它们不会自动定义。