<b>C++/VC++编程疑问问题及解答(二)</b>[VC/C++编程]
本文“<b>C++/VC++编程疑问问题及解答(二)</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
尺度程序库问题,再谈list的迭代器能否可以随机移动?
上篇文章中的"list的迭代器能否可以随机移动?"问题的回想:
由于list的内部实现是双向链表,链表就要求迭代器(指针)只能顺次早年向后(或从后向前)移动,顺次移动一个位置,因此list只定义了++和--操作符,而没有定义+、-、+=和-=等操作符.所以要想list的迭代器移动一段距离,就需求自己编程实现,用一个小循环就行了,代码以下:
#include <list>
using namespace std;
list<int> myList;
… // myList的初始化及其他操作
list<int>::const_iterator itList = myList.begin();
// itList向前移动len个距离
for ( int i= 0; i < len; i++ )
{
++itList;
}
... // 其他操作
上面对STL中的list的指针随机移动问题的注释不是很好,感激周星星的提醒,我们可以用STL的advance操作,我给出的代码的是advance针对list的一个大概的实现办法.这里我倡议利用advance操作替换我的那段代码.
advance操作是STL针对全部容器范例的一个通用的迭代器移动操作,它能按照容器范例的差别自动挑选合适的移动办法,关于随机存取容器(如vector和deque),迭代器可以直接移动到所需求的位置,关于非随机存取的容器(如list,map等),迭代器就需求渐渐往后移动,直到移到需求的位置.但是差别的STL实现版本对advance的实现大概是差别的.我们没有必要理解它毕竟是怎么实现的,会用便可.
尺度程序库问题,vector的resize()和reserve()函数的辨别
首先这两个函数有本质的辨别.reserve是容器预留空间,但并不真正成立元素对象,在成立对象之前,不能引用容器内的元素,因此当加入新的元素时,需求用push_back()/insert()函数.
resize是改变容器的大小,并且成立对象,因此,调用这个函数之后,便可以引用容器内的对象了,因此当加入新的元素时,用operator[]操作符,大概用迭代器来引用元素对象.
再者,两个函数的情势是有辨别的,reserve函数之后一个参数,即需求预留的容器的空间;resize函数可以有两个参数,第一个参数是容器新的大小,第二个参数是要加入容器中的新元素,假如这个参数被省略,那么就调用元素对象的默许构造函数.下面是这两个函数利用例子:
vector<int> myVec;
myVec.reserve( 100 ); //新元素还没有构造
for (int i = 0; i < 100; i++ )
{
myVec.push_back( i ); //新元素这时才构造
}
myVec.resize( 102 ); // 用元素的默许构造函数构造了两个新的元素
myVec[100] = 1; //直接操作新元素
myVec[101] = 2;
…
尺度程序库问题,vector的内存重分配问题
在利用vector时,一定要注意vector是动态分配内存的.固然利用vector很便利,但是假如不注意相关的问题,后果是很糟糕的.比方下面的程序:
struct ForwardProb
{
string m_SS;
string m_dictItem;
int m_index;
float m_forwardProb;
ForwardProb *preFP;
};
vector<ForwardProb> myVec;
for ( int i = 0; i < count; i++ )
{
ForwardProb thisFP;
…
thisFP->preFP = some previous pointer in myVec;
myVec.push_back( thisFP );
}
…
在这段代码中,由于每次thisFP都是新加入myVec中的,这样大概需求重新分配内存,即myVec在内存中的位置便大概发生了改变,那么每个元素中的指针preFP便大概变得无效了.
办理的办法:在利用myVec之前,先用reserve函数为vector预留出充足的空间,大概将指preFP针改成下标.
动态链接库与静态链接库
动态链接库和静态链接库的成立是很类似的,在Visual C++.net用成立项目时,在利用程序设置中挑选DLL或这静态库,便可以成立一个空的动态链接库/静态链接库的空项目.
静态链接库的成立和利用
假定成立一个staticLinkLib的静态链接库.在静态链接库的接口函数的定义情势以下:
extern "C" return_type interfaceFunctionName( parameter… );
注意这里加上extern "C"是必要的.别的在动态链接库对应的头文件里也要像这样声明,编译之后将动态链接库(.lib文件)和对应的头文件提交给用户利用便可.假定这两个文件是staticLinkLib.lib和staticLinkLib.h.
用户在利用动态链接库时,要包含上面的头文件staticLinkLib.h,并且在项目属性中的"链接器/输入"挑选静态链接库文件staticLinkLib.lib.以下图:
图一 VC.net下的项目属性设置
这样,用户在自己的利用程序便可以调用静态链接库中定义的接口函数了.
动态链接库的成立和利用
动态链接库的成立/利用和静态链接库基本相同,差别的地方在于接口函数的声明情势.动态链接库的接口函数声明情势以下:
extern "C" __declspec(dllexport) return_type interfaceFunctionName( parameter… );
别的,动态链接库编译之后生成一个动态链接库文件(dll)和一个.lib文件.提交时需求提交这两个文件和对应的接口的头文件.
用户利用动态链接库时,也需求在项目属性中的"链接器/输入"挑选对应的.lib文件,那么程序会自动调用.dll文件的.用户不需求包含上面提交的头文件,用户只需求按照规定的情势声明接口函数便可,情势以下:
extern "C" __declspec(dllimport) return_type interfaceFunctionName( parameter… );
这样,用户便可以在自己的利用程序中调用动态链接库中定义的接口函数了.
动态链接库中不能有屏幕输出语句,如cout << …等,因此调试时不太便利,这里没有研究动态链接库的调试办法.
静态链接库和动态链接库的一个很大的辨别还有,在静态链接库中不能在包含其他的动态链接库大概静态库;而在动态链接库中还可以再包含其他的动态/静态链接库.
以上是“<b>C++/VC++编程疑问问题及解答(二)</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |