1

これは私がここから見たインタビューの質問です:http: //www.careercup.com/question?id = 1707701

これについてもっと知りたい。ありがとう

4

3 に答える 3

8

浅いコピーは、「リモート所有権」を持っている場合に(主に)問題を引き起こします。最も一般的な形式は、オブジェクトが所有するデータへのポインタです。そのため、オブジェクトが破棄されると、オブジェクトが所有するデータも破棄されます。多くの人がこれに遭遇する1つの場所は、避けられない文字列クラスです。

// warning: bad code. Do *not* use.
class mystring { 
    char *data;
public:
    mystring() : data(NULL) {}
    mystring(char *init) {
        data = new char[strlen(init)+1];
        strcpy(data, init);
    }

    ~mystring() { delete [] data; }
};

int main() { 
     mystring s("This is a string");

     mystring t;

     t = s;
}

これは問題なくコンパイルされます。これらの正確な状況では、正常に動作しているように見える場合もあります。それはそれが本当に正しいという意味ではありません。に割り当てるstポインタはコピーされますが、ポインタが指すものはコピーされません。同じバッファへのポインタを含む2つのオブジェクトがありますそれらの1つが破棄されると、データに関連付けられているバッファーが削除されます。次に、ダングリングポインタがあります。これはまだバッファを参照しようとしていますが、バッファはもう存在しません。2番目のオブジェクトが破棄されると、同じメモリを再度解放しようとしますが、すでに解放されているため、未定義の動作につながります(つまり、何かが発生する可能性があり、通常は何か悪いことが起こります)。

浅いコピーには2つの一般的な方法があります。1つは「ディープ」コピーで、クラスのコピーコンストラクターと代入演算子をオーバーロードし、オブジェクトをコピー/代入するときに、新しいバッファーを割り当て、古いバッファーの内容を新しいバッファーにコピーします。 。

2つ目は、参照カウントです。バッファへの「生の」ポインタの代わりに、バッファへの「スマート」ポインタを使用します。スマートポインタは、バッファを参照しているオブジェクトの数を追跡し、バッファを参照しなくなったときにのみバッファ自体を解放します。

どちらも完全ではありません。特に大量のデータが関係している場合、ディープコピーは遅くなり、大量のメモリを使用する可能性があります。マルチスレッド環境では参照カウントが遅くなる可能性があります-参照カウントは複数のスレッドからアクセスできるため、1つのスレッドだけが一度に変更するように保護する必要があります(通常、参照カウントは少なくとも1桁遅くなります通常の増分/減分)。

于 2011-03-11T22:57:50.920 に答える
4

浅いコピーとは、まったく同じフィールド(およびポインター)を持つオブジェクトのコピーを作成する場合です。

クラス

class Car{
String name;
Owner* owner;
}

引数:

Owner owner
Car car1 = {"car", owner}
Car car2 = car1.copy
car2 = {"car", owner}

これで、car1のすべてのフィールドをcar2にコピーし、両方のフィールドの所有者が同じ所有者を指しています。所有者はポインターなので、ダングリングポインターがあるため、car1で行われた各変更はcar2に影響します。

しかし、深いコピーを作成する場合は、正しく取得する必要があります。

Car car3 = car1.deepCopy => will create ownerCopy = owner.copy
car3 = {"car", ownerCopy}

したがって、car1での変更はcar3にはまったく影響しません。

こちらが画像による説明です

于 2011-03-11T22:36:54.713 に答える
3

ウィキペディアには良い紹介があります

于 2011-03-11T22:29:35.513 に答える