gpt4 book ai didi

c++ - 模板化的 Pointer 类可以有一个虚拟析构函数吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:26:35 24 4
gpt4 key购买 nike

在使用自制指针类实现 pimpl 惯用语时,我遇到了一个令人惊讶的启示(我知道:为什么要自己动手?但请耐心等待)。以下三个文件包含一个最小示例:

指针.h:

#pragma once 

template <typename T>
class Pointer
{
public:
Pointer(T*p=0)
: _p(p)
{
}
virtual ~Pointer()
{
delete _p;
}
private:
void operator=(const Pointer&);
Pointer(const Pointer&);

private:
T*_p;
};

Foo.h:

#pragma once
#include "Pointer.h"

struct Foo
{
Foo();
~Foo();

private:
void operator=(const Foo&);
Foo(const Foo&);

private:
Pointer<struct FooPrivate> p;
};

主要.cpp:

#include "Foo.h"

int main(int argc, char* argv[])
{
Foo foo;
return 0;
}

别管 Foo.cpp 的内部结构是什么样子的。当我用 MSVC 2008 编译 main.cpp 时,我收到警告:

pointer.h(13) : warning C4150: deletion of pointer to incomplete type 'FooPrivate'; no destructor called

可以通过从指针析构函数中删除关键字 virtual 来避免警告。

这对我来说毫无意义。这个警告是合法的,还是 MSVC 编译器中的错误?如果是这样,我可以安全地忽略警告吗?

我知道在这种情况下将析构函数设为虚拟是没有意义的,但请记住,这只是一个最小的可编译示例。我的原始代码要复杂得多。

最佳答案

没有virtual ,只有一个地方会调用析构函数;在 ~Foo 内,此时您大概已经完全定义了 FooPrivate .如果 Pointer<FooPrivate> 的另一个实例是在别处创建的,您可能会收到警告,但由于您不知道,编译器可以告诉您您的行为是安全的。

virtual , 理论上你可以从 Pointer<FooPrivate> 推导出来,并且可以从 FooPrivate 的某处销毁该新对象没有完全定义。编译器不确定您不这样做,因此会发出警告。在这种微不足道的情况下,您可以安全地忽略它,但如果您确实需要虚拟析构函数,那么将它牢记在心可能是个好主意。

关于c++ - 模板化的 Pointer 类可以有一个虚拟析构函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6510323/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com