GeekBand-C++オブジェクト向け高度プログラミング(上)-Week 2

2356 ワード

1.コピーコンストラクタ


機能:あるオブジェクトを別のオブジェクトに初期化し、そのオブジェクトの内容をコピーできます.書き込みなしでコンパイラは自動的にデフォルトのコピーコンストラクタを生成し、デフォルトのコピーコンストラクタはソースオブジェクトの内容をバイトで新しいオブジェクトにコピーします.
例:
Rect::Rect(const Rect& r)  
{
    width = r.width;
    height = r.height;
}

浅いコピーと深いコピー


浅いコピー:
class TestClass {
    string *s;
public:
    TestClass(const TestClass& other);
};

TestClass::TestClass(const TestClass& other) {
    s = other.s;
}

浅いコピー後、2つのオブジェクトのsは同じ空間を指し、1つのオブジェクトが変更され、別のオブジェクトに影響を与え、プロファイル時に2回の削除エラーが発生しやすい.
深いコピー:
class TestClass {
    string *s;
public:
    TestClass(const TestClass& other);
};

TestClass::TestClass(const TestClass& other) {
    s = new string(*other.s);
}

深いコピー後、2つのオブジェクトのsは2つの異なる空間を指し、それらの内容は同じであるが、互いに影響しない.

2.代入関数


機能:割り当て演算子を使用してオブジェクトを別のオブジェクトに割り当てるときに呼び出されます.コンパイラのデフォルトの実装もバイト単位でコピーされます.
コピー構造に関する注意事項と区別:
TestClass a;
TestClass b = a; //  
TestClass c;
c = a; //  

代入関数では、代入元と同じオブジェクトかどうかを判断する必要があります.
TestClass& operator=(const TestClass& other) {
    if (this == &other) {
        return *this;
    }
    delete s;
    s = new string(*other.s);
    return *this;
}

このような判断を加えると、delete sを実行するときに自分のsを解放し、その後s=new string(*other.s)を行うときにエラーが発生するため、自分に値を割り当てるときにエラーが発生しやすい.sは実は自分のsです.

3.構造関数


機能:オブジェクトが破棄されるときに呼び出されます.構造関数では、一般的にリソースのクリーンアップや解放などが行われます.
例:
TestClass::~TestClass() {
    delete s;
}

4.スタックとスタック


関数のローカル変数は、スタック上に作成され、スタックに格納されます.関数の役割ドメインを離れると、スタック空間が回収され、スタック上のオブジェクトも破棄されます.動的に割り当てられたメモリは、スタックスペースに格納され、自動的に回収されず、手動で回収する必要があります.
int main() {
    int a; //  
    int *c = new int(1); //  
    delete c; //  
    return 0;
}

5.テンプレート


機能:クラスまたは関数を複数のタイプの場合に適用できます.
例:
template
class Container {
    T data[N];
};
Container a;
Container b;

これによりContainerというクラスは様々なタイプの要素を柔軟に格納することができる.
template
const T& max(const T& a, const T& b) {
    return a < b ? b : a;
}
max(1, 2);
max(1.0, 2.0);

これによりmax関数は異なるタイプに柔軟に対応できます.