2017-02-23 38 views
0

只要我不将构造函数的定义(B)移动到标头B.h,代码就会工作。Pimpl with unique_ptr:为什么我必须将接口的构造函数的定义移动到“.cpp”?

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{}; 

中号ain.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 

然而,我不明白为什么规则还涵盖构造函数(问题)。

我已阅读: -

+0

它是重要的*析构函数*。 –

+0

@Kerrek SB构造函数没有关系? – javaLover

+1

OT:把'Imp'放在'B'里面;和'class ... {public:'=='struct {' –

回答

2

构造函数需要销毁类成员,在它由异常退出的情况下。

我不认为使构造函数noexcept会帮助,虽然也许它应该。

+0

谢谢!不知何故明智的!算法在哪里?例如它是在std库中还是在编译器中嵌入? – javaLover

+0

@javaLover埋在编译器的深处。如果成员构造函数抛出,则以前的成员(按声明顺序)被销毁。如果构造函数体抛出,所有成员都被销毁。 – Potatoswatter