2011-03-10 19 views
7

私はしばらくの間、関数引数としてstructコンストラクタを次のように使用することは合理的ではない理由の良い説明を探しています。誰かが提供することはできますか?関数呼び出しでコンストラクタを使用しますか?

// Begin simple illustrative example C++ program  
#include<vector.h> 

struct Item 
{ 
    Item(double data, const int lead) 
    : m_grid(data), m_lead(lead) {} 

    double m_grid; 
    int m_lead; 
}; 

int main() 
{ 
    double img = 0.0; 
    int steps = 5; 
    std::vector<Item> images; 
    for (int i = 0; i < steps; i++) 
    { 
    img += 2.0; 
    images.push_back(Item(img,i)); 
    } 
    return 0; 
} 

私はpush_backはそれがconst参照によって引数の受け取り、その後、オブジェクトのコピーを作成しますので、これは、合法である

+1

C++ですか?あなたの言語を指定してください。 –

+0

申し訳ありません、はい、C++ – Evan

答えて

4

これは合法です。

コンストラクタを自分で呼び出すことはありません。あなたは実際には型名がItemの無名または "一時"オブジェクトを宣言しています。あなたは、オブジェクトが無名の作成時に構文が進化する方法を参照してください:あなたは機能のようなコンストラクタを呼び出しているかのように見えるにもかかわらず

Item a(img,i); // normal 
Item(img,i); // temporary 

を、あなたはありません。

とにかく、あなたはここで何をしているのか、関数の引数などでは、(それは1つであるため)「rvalue」として一時的なものを使用することができます。


ところで、古いiostream.hvector.hヘッダーを使用しないでください。 ISO標準C++では、それぞれiostreamvectorを使用する必要があります。 C++の標準ヘッダーは ".h"(inb4、下位互換性のために継承されたCヘッダーを無視します)で終わることはありません。

4

...コンストラクタは戻り値の型も声明もない印象の下にありました。コンストラクタの呼び出しは、右辺値である一時オブジェクトを作成します。 const参照は右辺値をバインドできます。このメソッドは渡されたオブジェクトを変更できませんが、コピーを作成できます。

+0

いいえ、プログラマーはコンストラクターを決して呼び出しません。私はあなたが言っていることを知っていますが、私はあなたの言葉が誤解を招くと思います。 –

3

関数呼び出しのように見えますが、式の項目(img、i)は、実際には一時オブジェクトの作成です。違いは、実行時には、スタック上のオブジェクトに対してメモリが割り当てられ、コンストラクタが呼び出されます。これが通常の関数呼び出しであれば、メモリは割り当てられません。

+0

さらに、オブジェクトの作成に関係する他のすべてのもの。 –

8

push_backに渡されるのはコンストラクタまたはその戻り値ではありません。 C++は、実際にはコンストラクタを使用して、名前のない一時オブジェクトを作成します。このオブジェクトは、関数呼び出しの間だけ存在します。典型的には、スタック上にある。これはpush_backに渡され、push_backは内容をベクターにコピーします。

+5

+1。しかし、 "表現の持続時間"は良いかもしれません。 –

関連する問題