首页 / 软件开发 / C++ / 使用::std::vector<>作为管理动态数组的优先选择
使用::std::vector<>作为管理动态数组的优先选择2010-07-14wangtianxing摘要: 本文介绍了C++标准库中的容器类vector,分析了它的优点,并且建议在应用程序中使用它作为动态数组的优先选择,而不是MFC的CArray<>等其他类模板。最后介绍了vector的接口和使用时的注意事项。在一些使用 MFC 的程序中,经常看到许多程序使用 CArray<>,由于 CArray<>的设计问题,造成使用它的代码的复杂化,增加了维护难度。因此建议使用 ::std::vector<> 代替 CArray<>。另外,也看到一些程序在用 malloc/realloc/free/new[]/delete[] 等手工管理内存。在应用程序中,手工管理内存是容易导致错误的,应该用 ::std::vector<> 之类的对象来管理动态数组。由于 MSDN 中关于 ::std::vector 的内容较少,我们在这里做一些介绍,供参考。不熟悉 CArray<>/WIN32 也没关系,这里提到它们的地方并不太多。1. CArray<> VS ::std::vector<> ?CArray<> 和 ::std::vector<> 一样,都是模板类,用于管理任意类型的对象的动态数组。都在解构时释放所管理的动态内存。因此都可以用于代替手工动态数组管理。但是,CArray<> 是在 C++ 标准化之前很多年(VC++2.0时代)设计的,当时对 C++程序设计,面向对象程序设计,模板程序设计等技术认识严重不足,尤其是当时对面向对象技术的错误信仰与宣传,造成 CArray<> 的设计有重大错误。在 C++ 语言标准化以后(1998),以及 VC++ 6.0 出世以后,提供了标准的::std::vector<> 模板,基本上在任何方面都要优于 CArray<>。Microsoft 由于要支持老的程序,因此一直保留了 CArray<>,但显然并没有打算按照新的思想去发展它(至少应该提供operator=(CArray const&)吧)。概括起来,CArray<> 与 ::std::vector<> 有以下不同:1) CArray<> 是 MFC 中的,::std::vector<> 存在于任何标准的 C++ 实现中。因此,你用熟了 CArray<> 也只能在 MFC 中用,若用熟了 ::std::vector<>,你可以在任何平台的任何 C++ 编译器下使用。使用标准的部件也有利于别人理解你的程序。 . CArray<> 继承了 CObject,仅仅为了实现 serialization,这是不恰当的, 违反了 "You don"t pay for what you don"t use." 的 C++ 设计原则。::std::vector<> 没有继承任何东西,只是实现了管理一个动态数组该做的事。2) CArray<> 不是一个恰当的值类型,例如下列操作都是不合法的:CArray<int,int> a;
CArray<int,int> b(a); // error, must use Copy().
b = a; // error, must use Copy().
b == a; // error, you must write your own.
b < a; // error, you must write your own.
与 CArray<> 相反,::std::vector<> 是一个认真设计的值类型,天生是可以拷贝构造和可赋值的。如果 T 是可比较的,那么 ::std::vector<T> 将自动地是可以比较的。此外,由于涉及到四个特殊成员函数;T(); // 缺省构造函数(default constructor)
~T(); // 解构函数(destructor)
T( T const& ); // 拷贝构造函数
T& operator=( T const& ); // 拷贝赋值函数
的自动生成,如果使用 CArray() 作为 T 的成员变量,那么上述的四个特殊函数中的后两个将无法自动生成,需要手工写:struct T
{
T() {}
T( T const& t )
{
a_.Copy( t.a_ );
i_ = t.i_;
d_ = t.d_;
s_ = t.s_;
}
T& operator = ( T const& t )
{
if( this != &t )
{
a_.Copy( t.a_ );
i_ = t.i_;
d_ = t.d_;
s_ = t.s_;
}
return *this;
}
private:
CArray<int,int> a_;
int i_;
double d_;
::std::string s_;
};
如果使用 ::std::vector<>:struct T
{
private:
::std::vector<int> a_;
int i_;
double d_;
::std::string s_;
};
上面列出的三个特殊成员函数都不需要写。好处是明显的:当你增减 T 的成员变量时,你不必到T(T const&) 和 operator=() 中去相应地增减。