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 时,它应该抛出编译时错误,因为我在私有部分中重载了赋值运算符。但我的编译进展顺利。我在这里遗漏了什么或做错了什么?

4

4 回答 4

6

This is because you are not copying instances, but pointers. Infact, you are losing the pointer to one of your instances.

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".

In addition to this, you also need to get the right fingerprint for the copy operator and ctor:

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

See: 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;
}

If you want to prevent copying of pointers, you'll need to create a class to encapsulate them, or you'll want to look at std::unique_ptr.


Edit:

Prior to C++11 the normal pattern for "disabling" an operator is to leave it undefined:

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

If someone tries to use it from outside the class, you'll get a compile time privacy error. If something inside the class tries to use it, you'll get a linker error (which is fine when you're expecting it but a headache when you're in crunch trying to fix a release-postponing issue and it's complaining about an undefined function).

With C++11 you can mark it as deleted, which will result in more specific errors:

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

I've taken to making these public because some of the compiler versions I work with check the visibility first leading to old-style errors, whereas making it public allows them to reach the "hey, this is disabled" and give you the newer, more helpful errors they have when they encounter a delete'd function/operator.

于 2013-09-30T06:35:42.080 回答
4

You're not copying the adapter object, you're just copying the pointer. Try *p = *q.

于 2013-09-30T06:35:34.677 回答
1

p并且q不是adapters,而是adapter*,它是指向 的指针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 回答