7

我担心使用带有智能指针的不完整类型以及如何删除指针。下面的代码安全吗?我认为不会,因为 main.cpp 会生成 Farm 的默认析构函数,它不会看到完整的类型。为了安全起见,我认为我应该创建一个看到完整类型的非内联析构函数。那是对的吗?

std::vector<Cow>如果我在 Farm 中使用,是否也一样?

农场.h

class Cow;

struct Farm
{
    Farm();
    // ~Farm();
    std::unique_ptr<Cow> cow;
};

农场.cpp

#include "cow.h"
// cow now complete

Farm::Farm()
{
    cow.reset(new Cow);
}

// Farm::~Farm() {}

主文件

#include "farm.h"

int main()
{
    Farm farm;
}

编辑:我尝试在没有析构函数的情况下使用 Visual Studio 进行编译,它显示错误 C2338:无法删除不完整的类型。我想这回答了我的问题。

4

2 回答 2

4

我认为您的代码不应该编译(并且它不在 gcc 中)

std::unique_ptr<Cow>使用std::default_delete<Cow>,并且std::default_delete<Cow>::operator()应该无法为不完整的类型实例化Cow

另请参阅unique_ptr 声明是否与 auto_ptr 声明不同,当其模板类型为不完整类型时,它是否是明确定义的?

所以你是对的:你需要确保在某个类型完整default_delete<Cow>::operator()的地方实例化。Cow这意味着Farm需要在这样的地方定义析构函数。

我刚刚注意到您的主题说“智能指针”,而问题指定unique_ptr. 对于 a ,答案会有所不同shared_ptr,因为std::shared_ptr<Cow>::reset()它是一个函数模板,它捕获传递给它的指针的(静态)类型并存储一个删除器。因此,shared_ptr您所需要的只是调用reset具有完整的类型Cow——析构函数的位置无关紧要。

于 2013-09-01T15:52:52.140 回答
1

的默认析构函数Farmunique_ptr包含 的析构函数,其中将包含 的析构函数Cow。即使在编译时没有可用的定义,也会完成此调用。预计链接器会在事后将事物连接起来。

于 2013-09-01T15:40:18.033 回答