3

私は C++ の初心者で、使用しているリソースには、次のステートメントd3 = d1 + d2;と書かれています。以下を呼び出します。

  • + 演算子
  • デフォルトのコンストラクタ
  • コピー コンストラクター
  • デストラクタ
  • 代入演算子
  • デストラクタ

結果が以前に宣言された変数に割り当てられているときにコピーコンストラクターが呼び出される理由と、2 つのコンストラクターが呼び出される理由がわかりません。

演算子は次のとおりです。

date& date::operator=(const date& other)
{
cout << "Date assignment op" << endl;
    if (this!=&other){
        day=other.day;
        month=other.month;
        year=other.year;
    }
    return *this;
}

date date::operator+(const date& other) const
{
    cout << "Date Operator + called" << endl;
    date temp;
    temp.day=day+other.day;
    temp.month=month+other.month;
    temp.year=year+other.year;
    return temp;
}
4

5 に答える 5

8

この式(d1 + d2)は、operator+ ( ) から戻るときに一時オブジェクトを生成しますreturn temp。「temp」からの一時ファイルの作成は、コピー コンストラクターを介して行われます。次に、これが d3 に割り当てられます。

于 2013-01-24T07:24:13.173 に答える
2

d1+d2 を計算すると、結果は一時オブジェクトになります。あるオブジェクトを別のオブジェクトに割り当てるために、コピー コンストラクターが呼び出されます。

于 2013-01-24T07:23:59.313 に答える
1

デフォルトではreturn、オブジェクトを値渡しすると、ソース オブジェクトから一時オブジェクトがコピー構築され、その一時オブジェクトが呼び出し元に渡されます。つまり、ステートメントd3 = d1 + d2;は基本的にこれを行っています。

date implicit_temp(operator+(d1, d2));
d3 = implicit_temp;

これは、内部で次のロジックに分割されます。

// The + operator 
date temp; // The default constructor
temp.day = d1.day + d2.day;
temp.month = d1.month + d2.month;
temp.year = d1.year + d2.year;
// return temp;
date implicit_temp(temp); // The copy constructor
temp.~date(); // Destructor
// Assignment operator
d3.day = implicit_temp.day;
d3.month = implicit_temp.month;
d3.year = implicit_temp.year;
implicit_temp.~date(); // Destructor

表示されている出力と同じ順序です。

コンパイラが RVO (戻り値の最適化) をサポートしている場合、ステートメントdateによって作成された一時オブジェクトを最適化して取り除くことができます。隠しパラメータreturnを渡すことで、演算子を介して変数を直接割り当てることができ、コードの動作をあたかものようにします。次のように書かれていました。d3returntempd3=

void date::operator+(const date& other, date& result) const
{
    date temp;
    temp.day=day+other.day;
    temp.month=month+other.month;
    temp.year=year+other.year;
    result = temp;
}

これは、ボンネットの下で次のロジックに分解されます。

// The + operator 
date temp; // The default constructor
temp.day = d1.day + d2.day;
temp.month = d1.month + d2.month;
temp.year = d1.year + d2.year;
// return temp; - Assignment operator
d3.day = temp.day;
d3.month = temp.month;
d3.year = temp.year;
temp.~date(); // Destructor
于 2013-01-24T10:41:01.997 に答える
0

それに頼るな

技術的には、あなたのブロックoperator+temp変数があり、それを一時オブジェクトに渡し、後で に渡す必要がありますoperator=

言い換えればoperator=、パラメータとして見られるのはtemp内部ではなく、そのコピーであり、ブロックoperator+よりも長く存続しなければならないため、発生させる必要があります。+=

ただし、次のいずれかの場合:

  • +return ステートメントは 1 つだけです (実際にはあります)。
  • +常に同じオブジェクトを返すすべての return ステートメントがあります

コンパイラは、一時ローカル変数を代入で使用される一時変数とマージすることにより、コピー オン リターンを最適化し、コピーをまったく除外できます。

これは、副作用を排除することもできる数少ない最適化の 1 つです (C++03 の 12.8.15 または C++11 の 12.8.31 を参照)。

コピー コンストラクターが呼び出されるかどうかは、最終的にはコンパイラーと必要な最適化のレベルに依存します。

(すべての明確化についてjuanchopanzaに感謝します)。

于 2013-01-24T08:35:29.913 に答える
0

コピー コンストラクターは、次の場合に呼び出されます。

A a=b,
when you return an object,
when you pass an object.

+演算子のオーバーロード関数は、実際にコピー コンストラクターを呼び出す一時オブジェクトを返します。

于 2013-01-24T07:22:08.413 に答える