【effective C++】06、不想使用编译器自动生成的函数,要明确拒绝

如上一篇博客【effective C++】05、了解C++默默编写并调用的函数中所介绍的那样,编译器会为类实现默认的函数,但在有些情况下我们不希望类有这些函数的功能,比如下面的例子:

class HomeForSale{/*~~~*/};

HomeForScale h1;
HomeForScale h2;
homeForScale h3(h1);
h1 = h2;
//由于每一笔资产都是独一无二的,我们不希望出现副本的拷贝情况,也就不希望有默认的拷贝构造函数和赋值操作赋重载

解决上面的问题的方法有两种:
(1)可以将对应的成员函数声明为private并且对该函数只声明而不予实现;
(2)实现一个专门的base class,派生类的调用可以避免编译器创建相应函数。

1、将copy构造函数和copy assignment操作赋声明为private

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

由于函数不可能被实现出来,所以不需要写函数的名称。
有了上述的定义,当用户试图拷贝HomeForSale的对象的时候,编译器就会阻止,如果不慎在类内部的成员函数和friend函数内那么做,连接器会给出提示。

2、封装阻止动作的base class

将上一种方法的链接期错误移到编译期是可能的,具体的做法如下:
(1)将copy构造函数和copy assignment操作赋声明为private;
(2)声明不在HomeForSale自身,而是base class内。

class Uncopyable{
    protected:
        Uncopyable(){}
        ~Uncopyable(){}
    private:
        Uncopyable(const Uncopyable&);
        Uncopyable& operator= (const Uncopyable&);
};

为了阻止HomeForSale对象被拷贝,唯一需要做的就是继承Uncopyable:

class HomeForSale:private Uncopyable{
    /*~~~*/
};

任何函数尝试拷贝HomeForSale的对象 的时候,编译器会尝试生成对应的copy构造函数和copy assignment操作符,这些函数又会尝试调用base class对应的兄弟,这些调用会被拒绝,因为base class的拷贝构造函数是private。

3、总结

拒绝编译器自动提供的机能,可以将对应的成员函数声明为private并且不进行实现;也可以像Uncopyable这样通过一个base class来实现。

猜你喜欢

转载自blog.csdn.net/u013108511/article/details/80571199