C++書き込みコピーコンストラクタ、リロード付与オペレータ、clone関数の注意点

1975 ワード

C++クラス:コピーコンストラクタを表示的に書き出すには、割り当てオペレータと解析関数を再ロードするのが良い習慣ですが、コンストラクタを書くときは、次のコードのようなエラーに注意する必要があります.
 
#include <iostream>
using namespace std;
 
class M{
public:
    M(){}
    M(const M &m){
       cout<<"copy construtor"<<endl;
       operator =(m);
    }
    M operator =(const M &m){   //      
       cout<<"operator ="<<endl;
       return *this;
    }
};
 
int main() {
    M m1;
    M m2;
    m2=m1;
    return 0;
}

コピーコンストラクション関数は、次の3つの場合に呼び出されます.
(1)インスタンス化されたクラスオブジェクトを用いて、クラスの別のオブジェクトをインスタンス化する.
(2)このクラスのオブジェクトを1つの関数のパラメータとして伝達する.
(3)関数の戻り値がクラスのオブジェクトである.特に、文Mに対しては、  M mm=m; (1)に属する場合、すなわち文M mm=m;呼び出しは、コンストラクション関数ではなくコピーコンストラクション関数です.ただし、リロード=オペレータの場合、戻り値が参照タイプでないと、プログラムの実行に深刻な問題が発生します.すなわち、上記の3つのケースのいずれかが呼び出される場合、または=オペレータを使用する場合、コピーコンストラクタとoperator=はループを再帰的に呼び出し、プログラムにデッドループが発生します.コピーコンストラクション関数とoperator=の間で呼び出しが繰り返されるためです.解決策:operator=の戻りタイプを参照タイプM&に変更し、operator=を呼び出すとコピーコンストラクタは呼び出されません.また、cloneを書く場合は、M clone(){cout<<