如何禁止C++默认成员函数
2017-07-22 13:26
162 查看
如何禁止C++默认成员函数
发表于 2016-03-02 | 分类于 C++ | 阅读次数 17前言
前几天在一次笔试过程中被问到C++如何设计禁止调用默认构造函数,当时简单的想法是直接将默认构造函数声明为private即可,这样的话对象的确不能直接调用。之后查阅了《Effective C++》之后得到了比较详尽的解释。了解C++的默认行为
当我们创建空类时,C++默认给我们生成了四种成员函数:构造函数
析构函数
拷贝构造函数(copy)
重载=的拷贝函数(copy assignment)
因此,当你写下如下的代码:
1 | class Empty{}; |
class Empty{ public: Empty(){...} //default构造函数 Empty(const Empty& rhs){...} //copy构造函数 ~Empty(){...} //析构函数 Empty& operator=(const Empty& rhs){...} //copy assignment操作符 };
至于copy构造函数和copy assignment操作符是不是有效取决于类的成员变量,例如:如果类成员有const变量或者引用,那么是不能重新赋值的。
拒绝使用编译器自动生成函数
书中提到了一个实际的应用场景。在房子销售时,每一套房子都是独一无二的(地理位置,装修等等),那么显然我们不想让别人使用拷贝构造函数或者copy assignment操作符。但是如果我们不写,那么编译器会自动生成。如果我们写了就会可能让别人利用。那么该怎么办呢?首先我们最自然的想法就是把这两个函数声明为私有,这样别人调用的时候可能会报错。我们的直觉是正确的。确实这样做可以行得通。于是我们如此写到:
class HomeForSale{ public: ... private: HomeForSale(const HomeForSale& hfs){...} HomeForSale& operator=(const HomeForSale& hfs){...} };
当然那么做并不是万事大吉了。因为member函数和友元函数仍然能调用私有成员函数。那么你可能又想到答案:我们无需定义成员函数,只需声明即可:
class HomeForSale{ public: ... private: HomeForSale(const HomeForSale&); HomeForSale& operator=(const HomeForSale&); };
那么member成员函数和友元函数调用时,在编译阶段没问题,在链接阶段会报错。那么还有没有更好的方案能够让代码在编译阶段就能检测出错误呢? 答案是肯定的。
我们为此建立一个基类:
class Uncopyable{ protected: Uncopyable(){} //允许derived对象的构造和解析 ~Uncopyable(){} private: Uncopyable(const Uncopyable&); //但阻止copying Uncopyable& operator=(const Uncopyable&); };
那么,为了阻止HomeForSale被拷贝,我们只需继承Uncopyable:
class HomeForSale:private Uncopyable{ ... };
C++11提出更为简洁的解决方案:
class HomeForSale{ public: HomeForSale(const HomeForSale&) = delete; HomeForSale& operator=(const HomeForSale&) = delete; };
总结
为驳回编译器自动生成的成员函数,可将相应成员函数声明为private并且不予实现。或者使用像Uncopyable这样的基类。或者使用C++11的新特性。在boost也有这样的基类:noncopyable。
相关文章推荐
- 如何禁止C++默认生成成员函数
- 如何禁止C++默认生成成员函数
- 如何禁止C++默认成员函数
- C++中的线程函数如何访问类中的成员变量
- C++四个默认成员函数&运算符重载
- c++的默认成员函数
- C++中空类有多少个默认成员函数
- C++空类的默认成员函数总结
- C++中的空类,编译器默认可以产生哪些成员函数
- C++中的默认成员函数
- C++中的空类,编译器默认可以产生哪些成员函数
- C++回顾之深浅拷贝、禁止拷贝、空类的默认成员
- C++中的空类,默认产生哪些类成员函数
- C++中的空类,编译器默认可以产生哪些成员函数
- C++ 空类默认产生的类成员函数
- C++ - 默认生成的成员函数
- C++对象布局及多态之虚成员函数如何调用
- 详解c++中类的六个默认的成员函数
- C++中,如何定义和使用指向成员函数的指针
- 【C++缺省函数】 空类默认产生的6个类成员函数