Rei*_*ica 5 c++ shared-ptr incomplete-type c++11
我有这样的头文件foo.h(省略了无关的东西):
#pragma once
#include <memory>
class Bar;
struct Foo
{
std::shared_ptr<Bar> getBar();
std::shared_ptr<const Bar> getBar() const
{
return const_cast<Foo*>(this)->getBar();
}
};
Run Code Online (Sandbox Code Playgroud)
非const重载getBar()在.cpp文件中实现,该文件也可以看到完整定义Bar.
当foo.h包含在另一个文件(没有看到定义Bar)时,VS 2010会给我一个这样的警告:
warning C4150: deletion of pointer to incomplete type 'Bar'; no destructor called
Run Code Online (Sandbox Code Playgroud)
在const重载getBar()(或实际上在从该重载实例化的标准库中的深处).
我的问题是这个警告是否可以安全地被忽略.
我看待它的方式,有两个std::shared_ptr<Bar>被调用的成员函数getBar() const:转换构造函数和析构函数.
// converting constructor
template <class Y>
std::shared_ptr<const Bar>::shared_ptr(std::shared_ptr<Y> &&r)
Run Code Online (Sandbox Code Playgroud)
这用于初始化返回值getBar() const的返回值getBar().这并未列出任何先决条件(C++ 1127.2.2.1§20-22),这些先决条件需要Y(Bar在我的情况下)完成.
// destructor
std::shared_ptr<const Bar>::~shared_ptr()
Run Code Online (Sandbox Code Playgroud)
27.2.2.2§1规定当被销毁的共享指针为空时,没有副作用.
我理解为什么我收到警告 - 析构函数代码也必须关注delete必须在存储指针上调用的情况,并且此代码确实会删除不完整的类型.但是我看到它的方式,在我的情况下永远无法实现,所以getBar() const是安全的.
我是正确的,还是我忽略了一个电话或其他可以getBar() const实际删除不完整类型的东西?
我找不到警告的理由.我也不能用clang/libc ++复制警告.
在一般情况下,给定shared_ptr<Bar>,没有看到的建设shared_ptr<Bar>,需要一个Bar*和可选的删除器,也没有办法知道,如果~Bar()是以往任何时候都调用.没有办法知道删除器存储在哪个shared_ptr<Bar>,并且给出了一些未知的删除器d,它存储在(例如)的shared_ptr<Bar>旁边,不需要调用.Bar*pd(p)~Bar()
例如,您Bar可能没有可访问的析构函数:
class Bar
{
~Bar();
};
Run Code Online (Sandbox Code Playgroud)
你Foo::getBar()可以像这样实现:
std::shared_ptr<Bar>
Foo::getBar()
{
// purposefully leak the Bar because you can't call ~Bar()
return std::shared_ptr<Bar>(new Bar, [](Bar*){});
}
Run Code Online (Sandbox Code Playgroud)
如果没有看到foo.cpp,编译器就无法知道.
这个警告对我来说看起来像编译器错误,或者可能是执行中的错误std::shared_ptr.
你能忽略这个警告吗?我不知道.在我看来,你正在处理实现中的错误,因此bug很可能意味着警告是真实的.但是假设完全符合实现,我认为没有要求Bar在您显示的代码中成为完整类型.
| 归档时间: |
|
| 查看次数: |
1322 次 |
| 最近记录: |