2014-01-07 3 views
9

移動コンストラクタが呼び出されなかったのはなぜですか?私のようになり<em>C++入門第5版</em>、から運動をやってる

練習13.50:あなたの 文字列クラスに移動操作にprint文を入れて、運動13.48からプログラムを再実行しますコピーが回避されるときに表示するベクターを使用§13.6.1(P。 534)。(P.544)

Stringは振る舞う練習のためのクラスでありますテンプレートを使用せずにstd::stringのようにします。 String.hファイル:デフォルトのため

class String 
{ 
public: 
    //! default constructor 
    String(); 

    //! constructor taking C-style string i.e. a char array terminated with'\0'. 
    explicit String(const char * const c); 

    //! copy constructor 
    explicit String(const String& s); 

    //! move constructor  
    String(String&& s) noexcept; 

    //! operator = 
    String& operator = (const String& rhs); 

    //! move operator =  
    String& operator = (String&& rhs) noexcept; 

    //! destructor 
    ~String(); 

    //! members 
    char* begin() const { return elements; } 
    char* end() const { return first_free; } 

    std::size_t size()  const {return first_free - elements; } 
    std::size_t capacity() const {return cap - elements;   } 

private: 

    //! data members 
    char* elements; 
    char* first_free; 
    char* cap; 

    std::allocator<char> alloc; 

    //! utillities for big 3 
    void free(); 

}; 

実装、String.cppからコンストラクタをコピーして移動:

//! default constructor 
String::String(): 
    elements (nullptr), 
    first_free (nullptr), 
    cap   (nullptr) 
{} 

//! copy constructor 
String::String(const String &s) 
{ 
    char* newData = alloc.allocate(s.size()); 
    std::uninitialized_copy(s.begin(), s.end(), newData); 

    elements = newData; 
    cap = first_free = newData + s.size(); 

    std::cout << "Copy constructing......\n"; 
} 

//! move constructor  
String::String(String &&s) noexcept : 
    elements(s.elements), first_free(s.first_free), cap(s.cap) 
{ 
    s.elements = s.first_free = s.cap = nullptr; 
    std::cout << "Move constructing......\n"; 
} 

Main.cpp

int main() 
{ 
    std::vector<String> v; 
    String s; 
    for (unsigned i = 0; i != 4; ++i) 
     v.push_back(s); 

    return 0; 
} 

出力:

Copy constructing...... 
Copy constructing...... 
Copy constructing...... 
Copy constructing...... 
Copy constructing...... 
Copy constructing...... 
Copy constructing...... 

このように、移動コンストラクタはまったく呼び出されませんでした。ベクトルがより多くのメモリを割り当てるときに、移動コンストラクタが呼び出されなかったのはなぜですか?

更新:

コンパイラの情報:

gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1) 

main.cpp印刷能力とそのouputを持つ:

int main() 
{ 
    std::vector<String> v; 
    String s; 
    for (unsigned i = 0; i != 4; ++i) 
    { 
     std::cout << v.capacity() << "\n"; 
     v.push_back(s); 
    } 

    return 0; 
} 

出力:

0 
Copy constructing...... 
1 
Copy constructing...... 
Copy constructing...... 
2 
Copy constructing...... 
Copy constructing...... 
Copy constructing...... 
4 
Copy constructing...... 
+2

を再現(http://ideone.com/9YaaZ0)、私は追加するとコンパイルに必要な定義が不足しています。どのコンパイラを使用していますか?ベクトルの容量をチェックします。おそらく、4つ以上の要素の前にスペースを確保していますか? –

+0

これはどのコンパイラですか? gccで動作します(4.7.2と4.8.2 - 私は現在アクセス可能なもののみです...) – Nim

+0

@MikeSeymour 4.73とスレッドを更新して容量印刷を追加しました。 –

答えて

1

は私が[私の作品] ...

~String() noexceptが問題を解決追加しています... MinGWの上のgcc 4.7.1で

関連する問題