vla*_*sch 5 c c++ boost smart-pointers qt4
我有c-Structure,我想嵌入一个cpp类而不会中毒我的全局命名空间,所以我不想包含c-header.
这就是为什么我想使用带有前向声明结构名称的智能范围指针(QScopedPointer
或boost::scoped_ptr
).
我不明白的是在编译时失败的两个提到的作用域指针的实现:
促进:
错误C2027:使用未定义类型'xxx'
template<class T> inline void checked_delete(T * x)
{
// intentionally complex - simplification causes regressions
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; // < here
(void) sizeof(type_must_be_complete);
delete x;
}
Run Code Online (Sandbox Code Playgroud)
在Qt中也是如此:
错误C2027:使用未定义类型'xxx'
template <typename T>
struct QScopedPointerDeleter
{
static inline void cleanup(T *pointer)
{
// Enforce a complete type.
// If you get a compile error here, read the section on forward declared
// classes in the QScopedPointer documentation.
typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ]; // < here
(void) sizeof(IsIncompleteType);
delete pointer;
}
};
Run Code Online (Sandbox Code Playgroud)
引用的文档没有帮助我.它表示前向声明的类的析构函数不必是内联的,并且必须在每个可能的范围内清除指定指针时都可用.但我的c结构没有析构函数.
所以我有两个问题:
我的c-Structure没有析构函数.
一方面,不.你的struct实际上有一个析构函数 - 隐式声明的析构函数.
无论如何,让我们继续吧.
delete pointer;
Run Code Online (Sandbox Code Playgroud)
在编译这段代码时,我们应该调用析构函数*pointer
.但是,如果*pointer
是不完整类型,我们无法知道要调用的析构函数.在这种情况下,标准[expr.delete]表示它会导致未定义的行为.
如果被删除的对象在删除时具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为是未定义的.
如您所见,如果您的结构没有非平凡的析构函数或释放函数(特定于类operator delete
),则它不是UB.但是,您可能可以在结构中添加析构函数 - 您将这样做.如果你没有解决这一点,它就变成了错误的bug.(编译器不必报告它;它只是UB,而不是非法代码.)所以它不被认为是一种好的做法.
因此,删除不完整的类型确实是我们应该避免的.为避免这种情况,我们使用了这个技巧.
typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; // < here
(void) sizeof(type_must_be_complete);
Run Code Online (Sandbox Code Playgroud)
因为sizeof(T)
非法代码T
是不完整类型,所以它可以减少编译时错误,因为UB导致程序疯狂.
尽管补偿速度较慢,我强烈建议您尽量包括它; 虽然你的结构很简单但没有operator delete
,但是可以在不修复的情况下添加它们,这会导致UB.