0
class adapter
{
     private:
    adapter& operator= (adapter& j)
    {
    cout<<"i m here"<<endl;
    }

    adapter(adapter&)
    {}

    public:
    adapter()
    {}
 };

 int main()
  {

    adapter* p = new adapter;

    adapter* q = new adapter;

    p = q;

    return 0;

  }

ここで q が p に代入されると、private セクションで代入演算子をオーバーロードしているため、コンパイル時エラーが発生するはずです。しかし、私のコンパイルはうまくいきます。ここで欠けているものや間違っているものはありますか??

4

4 に答える 4

6

これは、インスタンスではなくポインタをコピーしているためです。実際、インスタンスの 1 つへのポインタが失われています。

adapter* p = new adapter;
// translates to:
// void* ptr = alloc(sizeof(adapter));
// adapter* p = (adapter*)ptr;
// new (p) adapter(); // invoke the object's ctor.

adapter* q = new adapter;
// that allocated a new adapter on the heap and ctor'd it.

adapter x;
// this created an actual instance of adapter on the stack;
// when 'x' goes out of scope, because it's on the stack,
// it will be destroyed and it's destructor invoked.
adapter y;
// again, on the stack.

p = q;
// that copied the address of the second allocation into
// the first pointer, *losing* the first pointer. C++ does
// not have garbage collection, so this is called a leak.

x = y; // error: tried to use copy operator.
// this attempts to copy the instance "y" to the instance "x".

これに加えて、コピー オペレーターと ctor の正しいフィンガープリントも取得する必要があります。

private:
    adapter& operator=(const adapter&);
    adapter(const adapter&);

参照: http://ideone.com/K4rQdx

class adapter
{
private:
    adapter& operator= (const adapter& j);
    adapter(const adapter&);

public:
    adapter()
    {}
};

int main()
{
    adapter* p = new adapter;
    adapter* q = new adapter;

    *p = *q;

    return 0;
}

ポインターのコピーを防止したい場合は、それらをカプセル化するクラスを作成するか、std::unique_ptr を確認する必要があります。


編集:

C++11 より前では、演算子を「無効にする」ための通常のパターンは、未定義のままにすることです。

private:
    adapter& operator = (const adapter&); // name the parameter or not, it's optional.

誰かがクラス外から使用しようとすると、コンパイル時のプライバシー エラーが発生します。クラス内の何かがそれを使用しようとすると、リンカ エラーが発生します (予期している場合は問題ありませんが、リリース延期の問題を修正しようとして窮地に立たされていて、未定義の問題について不平を言っている場合は頭痛の種になります)関数)。

C++11 では、削除済みとしてマークすることができます。これにより、より具体的なエラーが発生します。

public:
    adapter& operator = (const adapter&) = delete;

私が使用しているコンパイラのバージョンの中には、最初に古いスタイルのエラーにつながる可視性をチェックするものがあるため、これらを公開することにしました。削除された関数/演算子に遭遇したときに発生する、より役立つエラー。

于 2013-09-30T06:35:42.080 に答える
1

pqは ではありませんadapteradapter*、へのポインタadapterです。

最悪の場合、メモリ リークが発生しています。

int main()
{
  adapter* p = new adapter; // first object of type adapter, p points to it
  adapter* q = new adapter; // second object of type adapter, q points to it
  p = q; // both p and q point to the second object now, first object lost
  // no delete statement, so second object lost too.
  return 0;
}

あなたがすべきことはどちらかです

int main()
{
   adapter p;
   adapter q;
   p = q; // won't compile
}

また

int main()
{
    std::unique_ptr<adapter> p = new adapter;
    std::unique_ptr<adapter> q = new adapter;
    p = q; // won't compile as unique_ptrs don't want you to let two variables point to the same thing
    p = std::move(q); // will compile as you invoke the move-assignment operator.
}

最初の方法を使用することをお勧めします。

于 2013-09-30T06:45:08.430 に答える
0

アダプター オブジェクトのアドレスのみをコピーしています。

于 2013-09-30T06:38:36.610 に答える