为什么普通的可复制类要求析构函数必须是普通的
Why trivial copyable class require the destructor must be trivial
基于c++标准。平凡的可复制类定义如下:根据9/5,
A trivially copyable class is a class that:
- has no non-trivial copy constructors (12.8),
- has no non-trivial move constructors (12.8),
- has no non-trivial copy assignment operators (13.5.3, 12.8),
- has no non-trivial move assignment operators (13.5.3, 12.8), and
- has a trivial destructor (12.4).
根据我的理解,平凡可复制的类是可以按位复制的。那么,为什么需要平凡的析构函数呢?
原因很简单。trivial copyable意味着在对象B之上复制一个对象A是有效的,并且定义了行为。显然,B的析构函数不会被调用,所以它必须是平凡的。
在N3797 3.8/4中有一个对象生命周期的描述,似乎涵盖了这种情况。但是,如果程序不依赖于析构函数的副作用,则可能存在关于存储重用和不调用非平凡析构函数的漏洞。
一个重要的析构函数可能意味着您正在删除一些指针。如果是这种情况,对类进行按位复制似乎很容易出错,因为这样就会有两个实例都试图删除同一个指针。
这只是一个猜测
在c++对象模型中,满足Trivially Copyable概念的类型在逻辑上是数据只是位块的类型。类型只是具有一些值的基本数据对象的集合。因此,将一个位块复制到某个存储是一个完全有效的操作,并且该存储(如果正确对齐)现在应该包含这样一个对象。此外,将一个位块复制到某个临时存储(不管对齐方式如何),然后将其复制回适当类型的对象,这是完全合理的。
c++允许所有这些对于平凡可Copyable类型。
如果一个类型真的只是一个比特块…为什么它的销毁不仅仅涉及内存释放?或者更重要的是,如果它的销毁需要做的不仅仅是释放内存,那么真的只是一个比特块吗?
c++的答案是否定的,它不是。或者更确切地说,我们不能证明它不仅仅是一个比特块。
这就是琐碎可复制性规则:它是关于证明的。在平凡的可复制性规则下,我们可以证明这样的类型只是一个比特块。其他类型可能是位块,这取决于这些函数的作用。但由于我们无法证明它们是否存在,因此我们禁止这样对待它们。
- 为什么使用析构函数会使类不可复制?
- 在调用其析构函数之前,是否有任何实际理由检查某些东西是否可破坏?
- 复制构造函数 C++ 在析构函数上返回奇怪的字母
- 如果我也使用复制构造函数并且重载 = 运算符,我是否需要析构函数?
- c++ 复制构造函数和析构函数
- 使用 std::function 作为成员函数,它捕获"this",并在析构函数之后从复制的 lam
- 为什么复制构造函数不是微不足道的,因为有一个用户定义的析构函数?
- 对象计数复制构造函数的调用次数比析构函数多
- 默认移动分配调用析构函数,复制分配不
- 为什么析构函数和复制构造函数使用对象数组显示此行为
- 使用shared_ptr时需要实现析构函数、复制构造函数、赋值运算符
- 通过复制将对象传递给 CUDA 内核会调用其析构函数并过早释放内存
- 抛出可由C++98和C++1x编译的析构函数.有更好的方法吗
- 如何在具有指向对象的指针数组的类中创建复制构造函数和析构函数,其中对象本身具有指向整数的指针数组
- 可观察行为和未定义行为 -- 如果我不调用析构函数会发生什么?
- 构造函数中的额外析构函数、复制构造函数、C++中的析构函数序列
- 复制构造函数和析构函数八叉树c++
- `不可复制`与自定义析构函数
- c++析构函数、复制构造函数和赋值操作符实践考试
- 为什么普通的可复制类要求析构函数必须是普通的