禁止对象之间的拷贝

如何禁止对象之间的拷贝?

将构造函数和析构函数中的任意一个设置为private,如下:

class A{
public:
    A(){};
private:
    ~A(){};
    A(const A&a){};
    A &operator=(const A&a){return a;}
};

A a;

 编译报错提示:Variable of type 'A' has private destructor.

我们知道,如果我们不显性的声明拷贝构造函数和重载=,那么编译器会为我们提供默认的拷贝构造函数和copy assignment函数。这样一来,对象间的拷贝就会发生,如果要禁止对象间的拷贝,那么就要显性的声明,无需定义。

class A{
public:
    A(){};
    ~A(){};
    A(const A&a){};
private:
    A &operator=(const A&a){return a;}
};

A c,d;
c=d;

 编译报错:'operator=' is a private member of 'A'

但是我们如果把友元函数写进class A,那就破坏了其封装性,也就破坏了我们禁止拷贝的意图。请看如下代码:

class A{
public:
    A(int i){_b=i;};
    ~A(){};
    A(A&a){};
    void printA() const
    {
        cout<<_b<<endl;
    }
    friend void copy(A &a, A &b);
private:
    A &operator=(A&a){return a;}
    int _b;
};

void copy(A &a, A &b)
{
    b._b=a._b;
}

int main(int argc, const char * argv[])
{
    A c(1);
    A d(2);
    copy(c,d);
    d.printA();
    return 0;
}

 运行结构是1,证明对象间拷贝成功。那么有什么简单的方法禁止拷贝,而且又很优雅呢?定义一个基类class noncopyable,让A去继承noncopyable,这样就A生成的对象不能拷贝了。

class noncopyable{
public:
    noncopyable(){}
    ~noncopyable(){}
private:
    noncopyable(const noncopyable&);
    const noncopyable &operator=(const noncopyable &);
};


class A : public noncopyable
{
...
};

A c(1);
A d(2);
d=c;

 编译报错:Object of type 'A' cannot be assigned because its copy assignment operator is implicitly deleted。此时,由于继承了noncopyable类,而noncopyable的运算符重载声明为private,故导致其子类拷贝失败。这是一种思路,若有些行为不想发生,可定义一个基类,声明该方法为private,而子类不去覆盖该方法就行了。友元函数也无法破坏这种设计,因为基类的友元函数无法破坏基类的封装性。友元函数和类是一对一的关系,无法破坏基类或者父类的封装性。

原文地址:https://www.cnblogs.com/howo/p/7456129.html