1. 程式人生 > >C++ vector::erase和無參建構函式的呼叫

C++ vector::erase和無參建構函式的呼叫

vector::erase

C++ vector的元素刪除,原始碼是這樣的:

template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::erase(const_iterator __position)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
    _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this
, "vector::erase(iterator) called with an iterator not" " referring to this vector"); #endif _LIBCPP_ASSERT(__position != end(), "vector::erase(iterator) called with a non-dereferenceable iterator"); difference_type __ps = __position - cbegin(); pointer __p = this
->__begin_ + __ps; this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p)); this->__invalidate_iterators_past(__p-1); iterator __r = __make_iter(__p); return __r; }

可知,C++將被刪除部分的後面所有元素作為一個集合向前移動了。
所以,假設我們需要清空元素,不要這樣寫:

int main()
{
    vector<int> v_int;
    for
(int i=0;i<10;i++){ v_int.push_back(i+1); } int size = v_int.size(); vector<int>::iterator it = v_int.begin(); while(size--) { cout<<*it<<" "; v_int.erase(it++); // attention ! cout<<"size: "<<v_int.size()<<endl; } return 0; }

它得到結果是這樣的:

1 size: 9
3 size: 8
5 size: 7
7 size: 6
9 size: 5

將例子中的it++改成it即可,那樣才能清空所有的元素。

無參建構函式的呼叫

形如Base instance()會呼叫類的無參建構函式嗎?
答案是否定的,C++會將其解釋成返回Base物件的函式。

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Base{
public:
    Base(){ cout<<"Base()..\n"; }
    Base(string str){ cout<<str<<endl; }
    ~Base(){ cout<<"~Base().. \n"; }
};

int main()
{
    //Base ins(); //empty parentheses interpreted as a function declaration
    Base ins;     //ok
    Base ins2("hello world");  //ok
    return 0;
}

不過有意思的是,有參建構函式卻是可以被這樣呼叫的。

有時,我們會遇到這樣的函式:

void show(const Base &b){
    //...
}

需要給該函式傳遞一個儲存在棧中的變數,要構造這樣的變數,我們可以簡單地這樣寫Base(). 它等價於Base b.
即:

    //show(Base("hello"));  //ok. output: hello     it's equal to 'Base b("hello"); show(b);'
    //show(Base());         //ok. output: Base()..  it's equal to 'Base b; show(b);'