当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 使用::std::vector<>作为管理动态数组的优先选择

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 使用::std::vector<>作为管理动态数组的优先选择


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 56 ::
收藏到网摘: n/a

使用::std::vector<>作为管理动态数组的优先选择
作者:wangtianxing

提交者:eastvc 发布日期:2003-9-19 17:34:41
原文出处:http://www.cpphelp.net/issue/vector.html


摘要: 本文介绍了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=() 中去相应地增减。

3) 没有现成的算法可以对 CArray<> 进行操作,而标准 C++ 里的标准算法大多都可以直接在
::std::vector<> 上运行。例如:

static int const init_vals[] = { 3, 1, 4, 1, 6, 9 };vector<int> a( init_vals, init_vals + 6 );*find( a.begin(), a.end(), 6 ) = 5; // 把6改成5sort( a.begin(), a.end() ); // 排序。

可以说,CArray<> 的主要设计