我“C++/VC++編程的疑難問題及解答”給出了三個關於C++/VC++編程的問題及其可能的解決方法。這篇文章再給出幾個問題,大家多給我提意見啊,有問題可以給我發信啊!
標准程序庫問題,再談list的迭代器是否可以隨機移動?
標准程序庫問題,vector的resize()和reserve()函數的區別
標准程序庫問題,vector的內存重分配問題
動態鏈接庫與靜態鏈接庫
標准程序庫問題,再談list的迭代器是否可以隨機移動?
上篇文章中的"list的迭代器是否可以隨機移動?"問題的回顧:
由於list的內部實現是雙向鏈表,鏈表就要求迭代器(指針)只能依次從前向後(或從後向前)移動,依次移動一個位置,因此list只定義了++和--操作符,而沒有定義+、-、+=和-=等操作符。所以要想list的迭代器移動一段距離,就需要自己編程實現,用一個小循環就行了,代碼如下:
#include
using namespace std;
list myList;
… // myList的初始化及其他操作
list::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 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 myVec;
for ( int i = 0; i < count; i++ )
{
ForwardProb thisFP;
…
thisFP->preFP = some previous pointer in myVec;
myVec.push_back( thisFP );
}