Pimpl with unique_ptr :为什么我必须将接口构造函数的定义移动到“.cpp”?
Pimpl with unique_ptr : Why do I have to move definition of constructor of interface to ".cpp"?
只要我不将构造函数(B
)的定义移动到 header B.h
.
,代码就可以工作。
B.h
class Imp; //<--- error here
class B{
public:
std::unique_ptr<Imp> imp;
B(); //<--- move definition to here will compile error
~B();
//// .... other functions ....
};
B.cpp
#include "B.h"
#include "Imp.h"
B::B(){ }
~B::B(){ }
Imp.h
class Imp{};
Main.cpp(编译我)
#include "B.h"
Error: deletion of pointer to incomplete type
Error: use of undefined type 'Imp' C2027
我能以某种方式理解必须将析构函数移至 .cpp
,因为 Imp
的析构可能会被调用 :-
delete pointer-of-Imp; //something like this
但是,我不明白为什么规则也涵盖构造函数(问题)。
我已阅读 :-
- Deletion of pointer to incomplete type and smart pointers
描述析构函数需要在 .cpp
. 中的原因
- std::unique_ptr with an incomplete type won't compile
关于默认析构函数的警告。
构造函数需要销毁class个成员,以防异常退出
我不认为制作构造函数 noexcept
会有帮助,尽管也许应该。
b.cpp 中的预处理可以通过以下命令生成,
g++ -E b.cpp >> b.preprocessed
如下,
# 1 "b.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "b.cpp"
# 1 "b.h" 1
class Imp;
class B
{
std::unique_ptr< Imp> imp;
public:
B(){}
~B();
};
# 2 "b.cpp" 2
# 1 "imp.h" 1
class Imp
{
};
# 3 "b.cpp" 2
B::~B(){}
这里很明显,class Imp
的声明在构造函数之后。
那么构造函数如何创建它不存在的东西呢? (仅前向声明是不够的)并且它清楚地表明构造函数定义必须在 b.cpp
文件中,以便它在 class Imp
声明之后出现并成为完整类型。
另一点是,我不认为这是使用疙瘩成语的正确方法。实现 class 应在源文件中声明和定义,源文件不能从外部访问,而不是将其保存在单独的头文件中。
只要我不将构造函数(B
)的定义移动到 header B.h
.
B.h
class Imp; //<--- error here
class B{
public:
std::unique_ptr<Imp> imp;
B(); //<--- move definition to here will compile error
~B();
//// .... other functions ....
};
B.cpp
#include "B.h"
#include "Imp.h"
B::B(){ }
~B::B(){ }
Imp.h
class Imp{};
Main.cpp(编译我)
#include "B.h"
Error: deletion of pointer to incomplete type
Error: use of undefined type 'Imp' C2027
我能以某种方式理解必须将析构函数移至 .cpp
,因为 Imp
的析构可能会被调用 :-
delete pointer-of-Imp; //something like this
但是,我不明白为什么规则也涵盖构造函数(问题)。
我已阅读 :-
- Deletion of pointer to incomplete type and smart pointers
描述析构函数需要在.cpp
. 中的原因
- std::unique_ptr with an incomplete type won't compile
关于默认析构函数的警告。
构造函数需要销毁class个成员,以防异常退出
我不认为制作构造函数 noexcept
会有帮助,尽管也许应该。
b.cpp 中的预处理可以通过以下命令生成,
g++ -E b.cpp >> b.preprocessed
如下,
# 1 "b.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "b.cpp"
# 1 "b.h" 1
class Imp;
class B
{
std::unique_ptr< Imp> imp;
public:
B(){}
~B();
};
# 2 "b.cpp" 2
# 1 "imp.h" 1
class Imp
{
};
# 3 "b.cpp" 2
B::~B(){}
这里很明显,class Imp
的声明在构造函数之后。
那么构造函数如何创建它不存在的东西呢? (仅前向声明是不够的)并且它清楚地表明构造函数定义必须在 b.cpp
文件中,以便它在 class Imp
声明之后出现并成为完整类型。
另一点是,我不认为这是使用疙瘩成语的正确方法。实现 class 应在源文件中声明和定义,源文件不能从外部访问,而不是将其保存在单独的头文件中。