从 STL 容器继承并删除"新"运算符以防止由于缺少虚拟析构函数而导致未定义的行为是否有意义?
Does it make sense to inherit from STL containers and delete `new` operators to prevent undefined behavior because of lacking virtual destructors?
我在这个论坛上被告知,我在书中读过它,还有其他答案指出继承 STL 容器从来都不是好事,因为 STL 容器析构函数不是虚拟的(通过基类指针删除派生对象时未定义的行为)。
但是,C++11 标准现在允许在编译时使用成员函数说明符(如delete
)进行按合同设计进行检查。我完全可以理解为什么继承一个 STL 容器,目标是用一个或两个成员函数进行扩展,最好将成员函数编码为算法。尽管如此,我还是遇到这样一种情况,即我将元素集合建模为概念,而元素本身是其他元素的容器。我需要实现访问子元素数据的双向迭代器 前向迭代器(例如 Collection::sub_element_iterator)。 在这种情况下,使用组合迫使我重新键入(适应)整个 std::vector 公共接口,只是为了使用迭代器扩展这个新集合。
在这种情况下,如果我仍然使用继承,并通过以下方式阻止堆分配,是否可以?
这是一个小模型:
#include <vector>
class not_heap_allocable
{
public:
void* operator new (std::size_t count) = delete;
};
template
<
typename Type,
template <typename T> class Allocator = std::allocator
>
class extended_vector
:
public std::vector<Type, Allocator<Type>>,
public not_heap_allocable
{
public:
typedef std::vector<Type> BaseType;
using BaseType::BaseType;
};
using namespace std;
int main(int argc, const char *argv[])
{
vector<int>* vNew = new extended_vector<int> ({0,1,2,3,4,5}); // Compile time error.
return 0;
}
然后导致编译时错误:
main.cpp: In function ‘int main(int, const char**)’:
main.cpp:31:64: error: use of deleted function ‘static void* not_heap_allocable::operator new(std::size_t)’
vector<int>* vNew = new extended_vector<int> ({0,1,2,3,4,5}); // Compile time error.
^
main.cpp:6:15: error: declared here
void* operator new (std::size_t count) = delete;
因此,extended_vector
不再指望人类不要滥用它。
这种方法似乎比继承protected
然后using
(公开)子类实际需要公开的基类成员更复杂,可能更不清楚。这样可以防止以这种方式公开继承的所有问题,同时不会通过探索新问题引入任何意想不到的问题。
编辑:我从boost中找到了我想要的东西:这个问题编写一个迭代器,使多个容器看起来像一个链接到boost::join
http://www.boost.org/doc/libs/1_46_1/libs/range/doc/html/range/reference/utilities/join.html,使您可以将多个范围合并为一个。
不,从不设计为具有派生的类派生是没有意义的。
实际上,您必须封装该类并将每个所需的功能转发给该封装的成员。
由于派生类仍然是一个基类,一旦它作为基类传递,你就会失去派生。
可以使用私有继承,但仍必须再次公开每个功能。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误