2012-08-13 41 views
2

我使用boost::scoped_ptr并在头文件中预先声明:什么翻译单位持有隐含定义的特殊成员函数?

//Bar.h 
class Foo; 

class Bar; 
{ 

private: 
    boost::scoped_ptr<Foo> _foo; 
}; 

我没有实现我自己的析构函数,因为智能指针将做的工作。

我将这个头文件包含在多个翻译单元中,并不是所有的都包含Foo定义。当试图编译时,我得到一个错误,scoped_ptr正在删除一个指针,指向不完整类型Foo

如果我在Bar.h中声明空的析构函数并在Bar.cpp中实现它,一切都很容易修复。

但是,如果析构函数是在头文件中实现的,我得到了同样的错误。

所以问题是:在哪个翻译单元做隐式定义的方法去?

+0

@DavidRodríguez-dribeas:谢谢,我选择了你的配方 – Andrew 2012-08-13 13:20:28

+0

由于同样的原因,我编辑了最后一句话。还删除了对* default构造函数/析构函数*的引用。在C++中,默认构造函数是不带参数的构造函数,无论它是否被隐式定义。 – 2012-08-13 13:22:15

+0

@DavidRodríguez-dribeas:是的,你说得对,谢谢 – Andrew 2012-08-13 13:23:54

回答

4

这个问题没有正确的表述。你想知道什么是

什么翻译单位持有暗含定义的特殊成员函数?

[这是一口]。答案是在每个翻译单元中,使用(odr-uses)它们。

为您的特定的使用情况,而且由于scoped_ptr析构函数需要的类型是完整的,你别无选择,只能申报Bar析构函数,即使空在具有的完整定义,翻译单元定义它Foo

或者,您可以使用不具有该限制的不同类型的智能指针。

4

所以问题是:在哪个翻译单元中实现了头部实现的方法?

在所有这些。也就是说,每个TU都有自己的(内联)实现。

你会在这里得到错误,因为显然析构函数需要定义Foo。这与无关,其中的析构函数已定义。如果您将其定义在自己的TU中,则该TU仍然需要知道Foo的定义。

+0

感谢您的回答!但是,链接器如何解决同一个函数的多个定义呢? – Andrew 2012-08-13 13:16:26

+1

@Andrew:*隐式定义的特殊成员函数*是'inline'。链接器解决了与其他任何'inline'函数一样的问题,通过选择其中一个定义并丢弃其余部分(这是一个实现细节,可以完成其他事情,但这就是我知道的每个链接器的行为方式) – 2012-08-13 13:17:53