C++代入演算子リロード関数(operator=)

13296 ワード

c++のリロード記号がよく理解されていないため、ここではいくつかの資料を参照して比較的詳細な解釈を提供し、読者や自分で調べるのに便利である.
ここではより詳細な説明がありますが、a=b=cの実行順序に関する説明は正しくありません.
例1
#include
#include
using namespace std;

class MyStr
{
private:
    char *name = NULL;
    int id;
public:
    MyStr() {cout << "default
"
<< endl;} MyStr(int _id, char *_name) //constructor { cout << "constructor" << endl; id = _id; name = new char[strlen(_name) + 1]; memcpy(name, _name, strlen(_name) + 1); } MyStr(const MyStr& str) { cout << "copy constructor" << endl; id = str.id; if (name != NULL) delete name; name = new char[strlen(str.name) + 1]; memcpy(name, str.name, strlen(str.name) + 1); } MyStr& operator =(const MyStr& str)// { cout << "operator =" << endl; if (this != &str) { if (name != NULL) delete name; this->id = str.id; int len = strlen(str.name); name = new char[len + 1]; memcpy(name, str.name, strlen(str.name) + 1); } return *this; } ~MyStr() { delete name; } }; int main() { MyStr str1(1, "hhxx"); cout << "====================" << endl; MyStr str2; str2 = str1; cout << "====================" << endl; MyStr str3 = str2; return 0; }

結果1
constructor
====================
default

operator =
====================
copy constructor

実行が表示されます.
str2 = str1

場合、付与演算子リロード関数が呼び出され、str 2が関数呼び出し者であり、str 1が関数呼び出しのパラメータ(str 2.xxx(str 1)に類似)であることは、通常の関数呼び出しと同様に理解できる. 付与演算子リロード関数パラメータは参照であり、一次オブジェクトのコピー構造を回避します. 同様に、レプリケーション演算子リロード関数関数の戻り値は参照であり、一度のオブジェクトのコピー構造も回避されます.戻り値タイプがMyStrの場合、関数が戻るとlinshi変数が作成され、このポインタが指すオブジェクトが一時変数にコピーされます. もちろん、オブジェクトを返さずに、戻り値をvoidに設定することもできます.しかし、オブジェクトまたは参照を返すときに、a=b=cと同様に、a=(b=c)に等しい連続的な付与を実現することができる.
例2(戻りタイプをMyStrに変更)
#include
#include
using namespace std;

class MyStr
{
private:
    char *name = NULL;
    int id;
public:
    MyStr() {cout << "default
"
<< endl;} MyStr(int _id, char *_name) //constructor { cout << "constructor" << endl; id = _id; name = new char[strlen(_name) + 1]; memcpy(name, _name, strlen(_name) + 1); } MyStr(const MyStr& str) { cout << "copy constructor" << endl; id = str.id; if (name != NULL) delete name; name = new char[strlen(str.name) + 1]; memcpy(name, str.name, strlen(str.name) + 1); } MyStr operator =(const MyStr& str)// { cout << "operator =" << endl; if (this != &str) { if (name != NULL) delete name; this->id = str.id; int len = strlen(str.name); name = new char[len + 1]; memcpy(name, str.name, strlen(str.name) + 1); } return *this; } ~MyStr() { delete name; } }; int main() { MyStr str1(1, "hhxx"); cout << "====================" << endl; MyStr str2; str2 = str1; cout << "====================" << endl; MyStr str3 = str2; return 0; }

結果2
constructor
====================
default

operator =
copy constructor
====================
copy constructor

実行
str2 = str1

を選択すると、関数はオブジェクトを返し、コピーコンストラクション関数を呼び出して一時変数を生成します.
例3(a=b=c実行順序の検証)
#include
#include
using namespace std;

class MyStr
{
private:
    char *name = NULL;
    int id;
public:
    MyStr() {cout << "default
"
<< endl;} MyStr(int _id, char *_name) //constructor { cout << "constructor" << endl; id = _id; name = new char[strlen(_name) + 1]; memcpy(name, _name, strlen(_name) + 1); } MyStr(const MyStr& str) { cout << "copy constructor" << endl; id = str.id; if (name != NULL) delete name; name = new char[strlen(str.name) + 1]; memcpy(name, str.name, strlen(str.name) + 1); } MyStr& operator =(const MyStr& str)// { if(name != NULL) cout << name << " = " << str.name << endl; cout << "operator =" << endl; if (this != &str) { if (name != NULL) delete name; this->id = str.id; int len = strlen(str.name); name = new char[len + 1]; memcpy(name, str.name, strlen(str.name) + 1); } return *this; } ~MyStr() { delete name; } }; int main() { MyStr str1(1, "str1"); cout << "====================" << endl; MyStr str2(2, "str2"), str3(3, "str3"); str3 = str2 = str1; cout << "====================" << endl; MyStr str4 = str2; return 0; }

結果3
constructor
====================
constructor
constructor
str2 = str1
operator =
str3 = str1
operator =
====================
copy constructor

 は,まず構造が3つのオブジェクトであり,nameはそれぞれstr 1,str 2,str 3であることがわかる.そして実行
str3 = str2 = str1

場合、str 2=str 1を実行し、オブジェクトstr 2がstr 1のnameを取得した後、str 3はstr 2が新しく取得したnameを取得する.