禁止拷贝、赋值和单例模式

这几天涉及到禁止类的拷贝与赋值,所以来写一下相关的东西。如有错漏,还望指摘。

首先,如果未定义构造函数、拷贝函数和赋值操作符的时候,C++会为类自动生成默认版本的。如果想禁止类的拷贝、赋值,甚至构造,有两种方法。

  1. 将其设为私有。
    这种方法很简单,就是写一个拷贝构造函数、赋值操作符,然后将其放在private限定符下。这样当外部想要拷贝或者赋值时,就会发现这个是私有的,禁止访问。
    使用这种方法时,函数本身仍是存在的,只是访问被限定了。此时于类的内部仍然可以进行拷贝或者赋值。所以当你仍然需要拷贝或者赋值,只是禁止从外部进行时,可以使用这种方式。
    示例:
    class Test {
    private:
        Test(const Test&) {};
        Test& operator = (const Test&) { cout << "assign" << endl; return *this; }
    public:
        Test() {};
        static void makeACopy(Test& left, const Test& right){
            left = right;
        }
    }
    
    int main(){
        Test a; //成功
        Test b = a; //失败,拷贝函数不可访问
        Test c(a); //失败,拷贝函数不可访问
        Test d;
        d = a; //失败,赋值操作符禁止访问
        Test::makeACopy(d,a); //成功,在类内可以进行赋值
    }
    
  2. 使用delete关键字
    使用delete关键字可以禁止函数的生成。此时无论从外部还是内部,都禁止对该函数的调用。好处是放在什么限定符下都可以,无论是private抑或是public。这样在将其定义成宏时,无需定义限定符,不用担心使用宏之后还需要重新定义限定符。
    示例
    class Test{
    public:
        Test() {};
        Test(const Test&) = delete;
        Test& operator = (const Test&) = delete;
    }
    
    int main(){
        Test a; //成功
        Test b = a; //失败,它是已删除的函数
        Test c(a); //失败,它是已删除的函数
        Test d;
        d = a; //失败,赋值操作符禁止访问
    }
    

这两种方法的优缺点涉及到接下来说的单例模式。

单例模式
所谓单例模式,就是说只能有一个实例存在。通常使用的方法是,由类内负责实例的生成,而禁止类外构造。
示例如下:

#define DISALLOW_COPY_AND_ASSIGN(class_name) \
    class_name(const class_name&) = delete;\
    class_name& operator = (const class_name&) = delete;
    
class Singleton{
private:
    //此时只能使用第一种方法,因为在类内我们仍然需要调用构造函数
    //我们只是禁止类外进行构造
    Singleton(arg) {};
public:
    //此时使用第二种方法禁止拷贝构造函数和赋值操作符
    //使得使用宏时,无须担心之后的函数会变成私有
    DISALLOW_COPY_AND_ASSIGN(Singleton)
    static Singleton* getInstance(arg){
        static Singleton instance(arg);
        return &instance;
    }
}

此时构造函数为私有,所以禁止类外构造。类外只能通过静态函数getInstance来获取唯一一个的静态实例。另外,使用静态变量的好处是,类外无需再关心什么时候析构这个类。静态变量随着程序的结束自动进行析构。但是需要注意的是!因为返回的是指针,所以类外可以进行手动析构,但是这会导致程序结束时发生错误。

原创文章 34 获赞 41 访问量 5960

猜你喜欢

转载自blog.csdn.net/qq_44844115/article/details/102520893
今日推荐