質問

ここで、本「C ++落とし穴」の項目56からの抽出物であります

  

これは、単純に見ることも珍しくありません   Yオブジェクトの初期化が書き込ま   3つの異なる方法のいずれか、かのように   彼らは同等であった。

Y a( 1066 ); 
Y b = Y(1066);
Y c = 1066;
  

実際の時点で、これらの3つのすべて   初期化はおそらくなります   同一のオブジェクトコードであります   生成されたが、彼らは同じではないです。   初期化として知られています   直接の初期化、およびそれはありません   正確に1つは期待するかもしれないものを。ザ・   初期化が行われて   Y :: Y(int型)の直接呼び出します。

     

BおよびCの初期化です   より複雑。実際に、彼らはあまりにもです   繁雑。これらは、両方のコピーです   初期化。の場合   Bの初期化、我々が要求しています   匿名の一時の作成   タイプYの値で初期化   1066私たちは、その後、コピーのパラメータとして、この匿名の一時を使用   クラスYを初期化するためのコンストラクタ   B。最後に、我々はのためのデストラクタを呼び出します   匿名の一時ます。

これをテストするために、私はデータメンバ(末尾に添付プログラム)との単純なクラスを行なったし、結果は驚くべきものでした。それは本の中で示唆したように、Cの場合のために、オブジェクトがコピーコンストラクタによって構築ではなくたと思われます。

言語規格が変更されたか、これは単にコンパイラの最適化機能である場合は、

誰もが知っていますか?私は、Visual Studio 2008を使用していました。

コードサンプルます:

#include <iostream>

class Widget
{
    std::string name;
public:
    // Constructor
    Widget(std::string n) { name=n; std::cout << "Constructing Widget " << this->name << std::endl; }
    // Copy constructor
    Widget (const Widget& rhs) { std::cout << "Copy constructing Widget from " << rhs.name << std::endl; }
    // Assignment operator
    Widget& operator=(const Widget& rhs) { std::cout << "Assigning Widget from " << rhs.name << " to " << this->name << std::endl; return *this; }
};

int main(void)
{
    // construct
    Widget a("a");
    // copy construct
    Widget b(a);
    // construct and assign
    Widget c("c"); 
    c = a;
    // copy construct!
    Widget d = a;
    // construct!
    Widget e = "e";
    // construct and assign
    Widget f = Widget("f");

    return 0;
}

出力:

Constructing Widget a

Copy constructing Widget from a

Constructing Widget c
Assigning Widget from a to c

Copy constructing Widget from a

Constructing Widget e

Constructing Widget f
Copy constructing Widget from f

私はDとEを構築した結果によって、最も驚きました。正確に言うと、私は空のオブジェクトが作成されるように期待していた、そしてそのオブジェクトが作成され、空のオブジェクトに割り当てられます。実際には、オブジェクトがコピーコンストラクタによって作成された。

役に立ちましたか?

解決

構文

X a = b;

AとBがタイプXのあるところには必ずコピーの建設を意味しています。

次のようなものは何でも変異体、
X a = X();

使用され、そこに起こって何も代入されていない、とされていない決して。構築し、のようなものになるでしょう割り当てます:

X a;
a = X();

他のヒント

コンパイラはbと同じになるようにケースcaを最適化することが許されます。さらに、コピーの構築と代入演算子の呼び出しは完全にとにかく、コンパイラによって排除することができますので、あなたが見るものは何でも、必ずしも異なるコンパイラ、あるいはコンパイラ設定で同じではありません。

C ++ 17のように、これらの3つのすべての<全角>なぜなら、多くの場合、<のhref = "HTTPと呼ばれるものの(Y::Y(int)は、単にexplicitを許可しませんc、でない限り)の等価です:// en.cppreference.com/w/cpp/language/copy_elision」のrel = "nofollowをnoreferrer">必須コピーの省略するます。

Y c = 1066;への暗黙的な変換の結果はYを初期化するのではなく、一時的に作成するために使用されるprvalueあるため、

でさえYは一cオブジェクトを作成します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top