C++ 为什么不';STL容器是否具有虚拟析构函数?
有人知道为什么STL容器没有虚拟析构函数吗 据我所知,唯一的好处是:C++ 为什么不';STL容器是否具有虚拟析构函数?,c++,stl,destructor,C++,Stl,Destructor,有人知道为什么STL容器没有虚拟析构函数吗 据我所知,唯一的好处是: 它将实例的大小减少一个指针(指向虚拟方法表)并 它使破坏和建设稍微快一点 缺点是以通常的方式对容器进行子类化是不安全的 编辑: 也许我的问题可以重新表述为“为什么STL容器的设计不允许继承?” 因为它们不支持继承,当一个人想要拥有一个需要STL功能和少量附加功能的新容器时(比如一个专门的构造函数或一个映射的默认值的新访问器,或者其他什么),他就不得不选择以下选项: 组合和接口复制:创建一个新模板或类,该模板或类作为私有成
- 它将实例的大小减少一个指针(指向虚拟方法表)并
- 它使破坏和建设稍微快一点李>
- 组合和接口复制:创建一个新模板或类,该模板或类作为私有成员拥有STL容器,并且每个STL方法都有一个直通内联方法。这与继承的性能一样,避免了虚拟方法表的成本(在重要的情况下)。不幸的是,STL容器有相当广泛的接口,因此这需要许多行代码来完成一些看似容易的事情
- 只创建函数:使用裸的(可能是模板化的)文件作用域函数,而不是尝试添加成员函数。在某些方面,这可能是一种很好的方法,但是封装的好处已经失去了
- 使用公共STL访问组合:让STL容器的所有者允许用户访问STL容器本身(可能通过访问器进行保护)。对于库编写器来说,这需要最少的编码,但对用户来说却不太方便。组合的一大卖点是减少代码中的耦合,但此解决方案将STL容器与所有者容器完全耦合(因为所有者返回真正的STL容器)
- 编译时多态性:编写时可能有点棘手,需要一些代码练习,并不适合所有情况
AS,C++ 11的Fuxer-<代码>使用声明,降低了构图成本。
< P>虚析构函数仅对继承方案有用。STL容器的设计目的不是从中继承(也不是受支持的方案)。因此,它们没有虚拟析构函数 >虚拟析构函数没有阻止类成为正确的子类。 < P>我猜想这是遵循C++哲学的,即不为不使用的特性付费。根据平台的不同,如果你不在乎虚拟析构函数,那么虚拟表的指针可能是一个巨大的代价。我认为斯特劳斯特鲁普在他的精彩论文中间接地回答了这个问题: 7闭幕词是各种各样的吗 上述设施 是否面向对象?哪一个? 使用什么定义 面向对象?在大多数情况下,我 我认为这些问题是错误的。 重要的是你能想出什么主意 清楚地表达,你能有多容易 从不同的角度组合软件 资源,以及效率和效率如何 结果程序的可维护性 是换句话说,你是如何支持的 良好的编程技巧和良好的编程能力 设计技术比设计更重要 标签和流行语。根本 这个想法只是为了改进设计和性能 通过抽象编程。你 要隐藏详细信息,请执行以下操作: 利用系统中的任何共性, 你想让这个价格合理。 我想鼓励你不要这样做 使面向对象成为无意义的 学期“面向对象”的概念 他经常被贬低 –由 把它等同于好, –通过等值 它使用单一语言,或 –由 接受一切 面向对象的 我认为 有——而且必须有——有用 超越面向对象的技术 编程和设计。但是, 我希望避免被完全误解 我想强调的是,我 不会尝试一个严肃的项目 使用一种编程语言 至少不支持古典音乐 面向对象编程的概念。 除了支持 面向对象编程,我想要—— C++提供的特性 除了那些支持 概念和概念的直接表达 关系
STL的构建主要考虑了三种概念工具泛型编程+函数样式+数据抽象==STL样式。OOP并不是表示数据结构和算法库的最佳方式,这并不奇怪。尽管OOP被用于标准库的其他部分,但STL的设计者发现,上述三种技术的结合比单独使用OOP要好。简而言之,这个库不是用OOP设计的,在C++中,如果你不使用它,它就不会与你的代码捆绑在一起。你不用的东西你不用付钱。类std::vector、std::list、,。。。是Java/C意义上的OOP概念。它们只是最好的解释中的抽象数据类型。正如已经指出的,STL容器的设计不是为了可继承。没有虚拟方法,所有数据成员都是私有的,没有受保护的getter/setter/helper。。正如你所发现的,没有虚拟析构函数
我建议您确实应该通过组合而不是实现继承来使用容器,以“has-a”的方式而不是“is-a”的方式使用容器。您不应该盲目地添加虚拟析构函数
template<typename _Tp, typename _Alloc = allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
class MyVector : private std::vector<int>
{
typedef std::vector<int> Parent;
public:
using Parent::size;
using Parent::push_back;
using Parent::clear;
//and so on + of course required ctors, dtors and operators.
};
class Dog {
public:
~Dog() {cout << "Dog is destroyed"; }
};
class Yellowdog : public Dog {
public:
~Yellowdog() {cout << "Yellow dog destroyed." << endl; }
};
class DogFactory {
public:
static shared_ptr<Dog> createYellowDog() {
return shared_ptr<Yellowdog>(new Yellowdog());
}
};
int main() {
shared_ptr<Dog> pd = DogFactory::createYellowDog();
return 0;
}
#include <vector>
#include <iostream>
using namespace std;
class Test
{
int val;
public:
Test(int val) : val(val)
{
cout << "Creating Test " << val << endl;
}
Test(const Test& other) : val(other.val)
{
cout << "Creating copy of Test " << val << endl;
}
~Test()
{
cout << "Destructing Test " << val << endl;
}
};
class BaseVector : public vector<Test>
{
public:
BaseVector()
{
cout << "Creating BaseVector" << endl;
}
virtual ~BaseVector()
{
cout << "Destructing BaseVector" << endl;
}
};
class FooVector : public BaseVector
{
public:
FooVector()
{
cout << "Creating FooVector" << endl;
}
virtual ~FooVector()
{
cout << "Destructing FooVector" << endl;
}
};
int main()
{
BaseVector* ptr = new FooVector();
ptr->push_back(Test(1));
delete ptr;
return 0;
}
Creating BaseVector
Creating FooVector
Creating Test 1
Creating copy of Test 1
Destructing Test 1
Destructing FooVector
Destructing BaseVector
Destructing Test 1