• Effective C++(6) 如何拒绝编译器的自动生成函数


    问题聚焦:
    如果不希望class支持某一成员函数,那么不声明和定义它就可以了,但是这一策略对与拷贝构造函数和重载赋值操作符并不起作用。
    因为如果不声明它们,那么当尝试调用它们的时候,编译器会为你声明和定义它们。
    这显然不是你所希望看到的。

    方法:将这类你不想使用并且也不想编译器为你声明的函数声明为private, 而不实现它们。
    原理:
    编译器自动生成的函数都是public
    声明一个函数可以阻止编译器自动生成该函数
    令这个函数为private可以阻止人们调用它
    缺陷:
    member函数或friend函数可以调用它们,导致链接错误。
    Demo:

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


    上面的方案虽然有一个小小的缺陷,但是还是可以让人接受的,毕竟链接错误不是那么的不可接受。
    很多时候我们总是希望尽可能地找到错误,毕竟链接错误远不如编译错误那样相对容易解决一点。
    这也是这个方案可以优化的地方(尽管我觉得很多时候可以不这么做)

    方案二:在方案一的基础上,将链接期错误移至编译器。

    先来看看demo.
    Demo:

    class Uncopyable {
    protected:
        Uncopy() {}
        ~Uncopy() {}
    private:
        Uncopyable (const Uncopyable&);
        Uncopyable& operator=(const Uncopyable&);
    };
    //  为了阻止编译的自动生成,我们唯一需要做的就是继承Uncopyable
    
    class  HomeForSale: private Uncopyable {
        ......
    };

    原理:
    当尝试拷贝操作时,编译器会尝试调用父类的对应的拷贝构造函数和重载赋值操作符,这些调用会被编译器拒绝,因为其base class的拷贝函数是private
    从而报出编译错误。

    小结:
    为了阻止编译器的自动生成功能,可以将相应的成员函数声明为private并且不予实现。
    使用向Uncopyable这样的base class也是一种做法。


    参考资料:
    《Effective C++ 3rd》
  • 相关阅读:
    类 2020年8月19
    随便一写,明天改正
    os模块 2020年8月16
    time 模块 2020年8月16
    collections模块 2020年8月16
    正则跟re模块内容2020年8月16日
    【C++设计模式二】C++工厂模式
    【C++设计模式一】C++简单工厂模式
    【01-springmvc快速入门、组件解析】
    03-【Spring 的 AOP】
  • 原文地址:https://www.cnblogs.com/suzhou/p/3638966.html
Copyright © 2020-2023  润新知