如何禁止C++默认生成成员函数
2016-07-04 00:00
239 查看
前几天在一次笔试过程中被问到c++如何设计禁止调用默认构造函数,当时简单的想法是直接将默认构造函数声明为private即可,这样的话对象的确不能直接调用。之后查阅了《Effective c
前几天在一次笔试过程中被问到c++如何设计禁止调用默认构造函数,当时简单的想法是直接将默认构造函数声明为private即可,这样的话对象的确不能直接调用。之后查阅了《Effective c++》之后得到了比较详尽的解释。了解c++的默认行为:当我们创建空类时,c++默认给我们生成了四种成员函数:构造函数 析构函数 拷贝构造函数(copy) 重载=的拷贝函数(copy assignment) 因此,当你写下如下的代码: 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提出更简单的解决方案:Delete。 class HomeForSale{ public: HomeForSale(const HomeForSale&) = delete; HomeForSale& operator=(const HomeForSale&) = delete; }; 总结:为驳回编译器自动生成的成员函数,可将相应成员函数声明为private并且不予实现。或者使用像Uncopyable这样的基类。或者用C++11的新特性:delete。在boost也有这样的基类:noncopyable。 (责任编辑:最模板) |
相关文章推荐
- 工厂方法C++实现
- C++中的执行时间测量
- 笔记——《C程序性能优化》[日】片山善夫
- 浅谈C++类(5)--友元
- 浅谈C++类(7)--析构函数
- C++中的rand()、srand()
- 浅谈C++类(1)--概念和构造函数
- c语言 error redefinition of 'xxx' 解决
- 一起talk C栗子吧(第一百七十一回:C语言实例--关闭终端中的回显功能二)
- C++之类和对象的使用(一)
- C语言文件的编译与执行的四个阶段
- c语言学习笔记45
- C语言中怎样判断汉字
- Visual C++开发工具与调试技巧整理
- Effective C++: lambda表达式与闭包.
- 简单的坦克大战模拟小游戏
- c++ 面试整理
- C的结构体和C++结构体
- C语言 求两个数的最大公约数
- C语言 将三个数按从大到小输出