C++:标准string或者STL容器不含virtual析构函数,所以不应该被继承——摘自Effective C++中文版第三版P42

即使class完全不带virtual函数,被“non-virtual析构函数问题”给咬伤还是有可能的。举个例子,标准string不含任何virtual函数,但有时候程序员会错误的把它当做base class:

1 // 馊主意,std::string有个non-virtual析构函数
2 class SpecialString: public std::string{
3     ...
4 };

乍看似乎无害,但如果你在程序任意某处无意间将一个pointer to SpecialString转换成一个pointer to string,然后将转换所得的那个string指针delete掉,你立刻被流放到“行为不明确”的恶地上。

 1 SpecialString* pss = new SpecialString("Impending Doom");
 2 std::string* ps;
 3 ...
 4
 5 // SpecialString* => std::string*
 6 ps = pss;
 7 ...
 8
 9 // 未有定义,现实中*ps的SpecialString资源会泄露,
10 // 因为SpecialString的析构函数没被调用
11 delete ps;

相同的分析适用于任何不带virtual析构函数的class,包括所有STL容器,如vectorlistsettr1::unordered_map等等。如果你曾经企图继承一个标准容器或任何其他“带有non-virtual析构函数”的class,拒绝诱惑吧。(很不幸C++没有提供类似Java的final class或C#的sealed class那样的“禁止派生”机制)

原文地址:https://www.cnblogs.com/pepetang/p/11669915.html

时间: 2024-08-05 07:03:38

C++:标准string或者STL容器不含virtual析构函数,所以不应该被继承——摘自Effective C++中文版第三版P42的相关文章

【C++标准库】STL容器

STL容器的共通能力 所有容器提供的都是"value语义"而非"reference语义".容器进行元素的安插动作时,内部进行copy或者move,而不是管理元素的reference. 元素在容器内有其特定顺序. 一般,各项操作并非绝对安全,调用者需要确保传给操作函数的实参符合条件. const vector<int> v1 = { 1,2,3,4,5,6 }; //使用初值列初始化 vector<float> v2(v1.begin(), v

C++笔记(6):标准模板库STL:容器、迭代器和算法

STL(Standard Template Library)是C++标准库的一部分.STL的代码从广义上讲分为三类:容器.迭代器和算法. 1.容器 2.迭代器 3.算法  -------------------------------------------------------------------------------------------------------------------------- 1.容器 顺序容器容器是特定类型对象的集合.顺序容器为程序员提供控制元素存储和访问

6.5-数据结构&amp;算法-标准模板STL/STL容器/向量

一.标准模板库(STL) 1.定义了一系列的容器模板,实现泛型化的数据结构. 1)向量(vector),内存连续,支持下标访问和随机迭代,只有在尾部进行插入和删除效率才比较高. 2)列表(list),内存不连续,不支持下标访问和随机迭代,在任何位置进行插入和删除效率都很高. 3)双端队列(deque),内存连续,支持下标访问和随机迭代,在首尾两端进行插入和删除效率都比较高. 以上三种合称为线性容器. 4)堆栈(stack),后进先出 5)队列(queue),先进先出 6)优先队列(priorit

标准模板库(STL)学习探究之vector容器

标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据.为了可以使用vector,必须在你的头文件中包含下面的代码:#include <vector>构造函数. Vectors 包含着一系列连续存储的元素,其行为和数组类

stl容器学习——queue,stack,list与string

目录 string stack queue list 点击上面的内容可以实现跳转哦 简介:本文记录了对string list queue stack四个容器的学习总结,包含有四种容器常用的函数介绍和一些使用过程中碰到的细节总结,在list容器中介绍了迭代器的使用. 头文件 想要用哪一种容器,就要加上对应的头文件 比如想要使用queue , 就要加上 #include<queue> 以此类推,想要使用STL库中的容器,只要加上它们的头文件就好. string 目录部分 1.string的定义及初

关于C++标准模板库(STL)的一些基本使用

vector vector可以理解成变长数组,即长度根据需要而自动改变的数组 头文件:#include <vector> 定义:vector<typename>name; vector内可以通过下标或者迭代器(iterator)访问(只有vector和string才允许使用v.begin()+3这种迭代器加整数的写法) v.push_back(value) 时间复杂度:$O(1)$ v.pop_back() 时间复杂度:$O(1)$ v.size() 返回的是unsigned类型

C++STL容器简析

标准STL序列容器:vector.string.deque和list.标准STL关联容器:set.multiset.map和multimap.非标准的关联容器hash_set.hase_multiset.hash_map和hash_multimap. (1)vector容器vector的数据安排以及操作方式,与array非常相似.两者的唯一区别在于空间的运用的灵活性.array是静态空间,一旦配置了就不能改变.vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素.因此,

c++标准库和stl

C++中有三大重要的标准库,为string.vector.bitset,他们每个都是一个类,对应的命名空间均为std.string类的对象可以存 储一个字符串,相应于C中存储字符串的方式,C++的优点是,在创建对象时可以不指定长度,在连接和删除中,只需要使用进行算符重载后了的“+”和 “-”.vector类的对象可以存储一个数组,可以int,char,string等,使用时,就像一个栈一样,通过push_back. pop_back等进行操作,这是与一般数组不一样的地方. String 类 1 

如何选择STL容器中对象的删除方法

备注:唯一从容器中除去一个元素的方法是在那个容器上调用一个成员函数. 以下介绍删除不同类型的容器中满足某种条件的值的方法,某种条件指的是 bool badValue(int value)返回true的情况. 1.序列容器 for(SeqContainer<int>::iterator i = c.begin(); i != c.end(); /*nothing*/) { if(badValue(*i)) { //something to do i = c.erase(i); } else ++