在c ++中限制对象副本

Chr*_*ris 0 c++

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;

  }
Run Code Online (Sandbox Code Playgroud)

这里当q被赋给p时,它应该抛出编译时错误,因为我在私有部分重载了赋值运算符.但我的汇编很顺利.我在这里失踪或做错了什么?

kfs*_*one 6

这是因为您不是复制实例,而是指针.事实上,您正在丢失指向其中一个实例的指针.

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".
Run Code Online (Sandbox Code Playgroud)

除此之外,您还需要为复制操作员和ctor获取正确的指纹:

private:
    adapter& operator=(const adapter&);
    adapter(const adapter&);
Run Code Online (Sandbox Code Playgroud)

请参阅: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;
}
Run Code Online (Sandbox Code Playgroud)

如果要防止复制指针,则需要创建一个类来封装它们,或者您需要查看std :: unique_ptr.


编辑:

在C++ 11之前,"禁用"运算符的正常模式是保持未定义:

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

如果有人试图从课外使用它,您将收到编译时隐私错误.如果类中的某些东西试图使用它,你会得到一个链接器错误(当你期待它时这很好但是当你处于紧张状态时试图修复一个推迟推迟的问题并且它抱怨未定义时很头疼功能).

使用C++ 11,您可以将其标记为已删除,这将导致更具体的错误:

public:
    adapter& operator = (const adapter&) = delete;
Run Code Online (Sandbox Code Playgroud)

我已经开始公开这些因为我使用的一些编译器版本检查可见性首先导致旧式错误,而将其公开允许它们达到"嘿,这是禁用的"并且给你更新的,他们遇到删除函数/运算符时遇到的更多有用错误.