Item11 Prefer deleted functions to private undefined ones

[复制链接]

该用户从未签到

759

主题

763

帖子

4660

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4660
跳转到指定楼层
楼主
发表于 2018-6-4 16:14:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
如果你把你的代码提供给其他开发者,但是却不想让其他人调用某些函数,这个时候你只需要不声明这个函数就可以了,但是有的时候你拿到了这个函数声明,但是却又不能让其被调用这就不好办了。典型的比如说赋值成员函数,默认构造成员函数等。这个时候通用的做法是将其设置为私有的,通过访问权限来避免被调用。
  1. class base {
  2. private:
  3.    base& operator=(const base& other);
  4. };

  5. int main() {
  6.   base b,a;
  7.   b = a;
  8. }
复制代码
上面的调用就会出现编译时错误。
  1. delete.cc: In function ‘int main()’:
  2. rror: ‘base& base::operator=(const base&)’ is private
  3.     base& operator=(const base& other);
  4.           ^
  5. error: within this context
  6.    b = a;
复制代码
标准库中的流就是一个不可赋值拷贝的类,其实现方法就是如此,这种方法有两个缺点,第一个就是出错信息过于隐晦,并不是这个函数不可被调用,只是权限不够而已,第二个则是这个类只能用于类成员函数,对于普通的函数则无能为力,因为对于普通函数来说没有权限的概念。C++11给我们提供了delete关键字用于删除某个函数,使用这个关键字可以完美解决上面这个方法的不足之处。
  1. class base {
  2. public:
  3.    base& operator=(const base& other) = delete;
  4. };

  5. int main() {
  6.   base b,a;
  7.   b = a;
  8. }
复制代码
编译会出错,显示这个函数被delete了,最重要的是delete可以应用于普通的函数,典型的用法就是避免某些隐式转换。
  1. bool isLucky(int number);

  2. if (isLucky('a'))....
  3. if (isLucky(true))....
  4. if (isLucky(3.5))....
复制代码
double,bool,char都可以隐式转换为int,这个函数的本意是接受一个整型,但是现在因为隐式转换的问题,导致这个函数变得不可控了。通过delete关键字可以解决这个问题。
  1. bool isLucky(char) = delete;
  2. bool isLucky(bool) = delete;
  3. bool isLucky(double) = delete;
复制代码
通过把这些重载函数都delete,这样就避免了隐式转换,充分利用了delete和重载函数决议的规则。delete除了上面这个技巧性的应用外,还可以避免不必要的模板具现化。
  1. template<typename T>
  2. void processPointer(T* ptr)
复制代码
对于上面这个模板,我们不需要对void*和char*做处理,因此我们必须禁止void*和char*的具现化,这个时候只要结合模板特化和delete即可实现这一功能。
  1. template<>
  2. void processPointer<void>(void*) = delete;

  3. template<>
  4. void processPointer<char>(char*) = delete;
复制代码
现在当我们使用这个模板的时候就无法具现化成void*和char*了,而这个功能是C++98无法做到的, 对于C++98来说实现的唯一途径就是借助于成员函数的访问权限,然后模板特化是无法在类的作用域内定义的。

分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表