Item11 Prefer deleted functions to private undefined ones

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

class base {
 private:
   base& operator=(const base& other);
};

int main() {
  base b,a;
  b = a;
}

上面的调用就会出现编译时错误。

delete.cc: In function ‘int main()’:
rror: ‘base& base::operator=(const base&)’ is private
    base& operator=(const base& other);
          ^
error: within this context
   b = a;

   标准库中的流就是一个不可赋值拷贝的类,其实现方法就是如此,这种方法有两个缺点,第一个就是出错信息过于隐晦,并不是这个函数不可被调用,只是权限不够而已,第二个则是这个类只能用于类成员函数,对于普通的函数则无能为力,因为对于普通函数来说没有权限的概念。C++11给我们提供了delete关键字用于删除某个函数,使用这个关键字可以完美解决上面这个方法的不足之处。

class base {
 public:
   base& operator=(const base& other) = delete;
};

int main() {
  base b,a;
  b = a;
}

   编译会出错,显示这个函数被delete了,最重要的是delete可以应用于普通的函数,典型的用法就是避免某些隐式转换。

bool isLucky(int number);

if (isLucky('a'))....
if (isLucky(true))....
if (isLucky(3.5))....

   doubleboolchar都可以隐式转换为int,这个函数的本意是接受一个整型,但是现在因为隐式转换的问题,导致这个函数变得不可控了。通过delete关键字可以解决这个问题。

bool isLucky(char) = delete;
bool isLucky(bool) = delete;
bool isLucky(double) = delete;

   通过把这些重载函数都delete,这样就避免了隐式转换,充分利用了delete和重载函数决议的规则。delete除了上面这个技巧性的应用外,还可以避免不必要的模板具现化。

template<typename T>
void processPointer(T* ptr)

   对于上面这个模板,我们不需要对void*char*做处理,因此我们必须禁止void*char*的具现化,这个时候只要结合模板特化和delete即可实现这一功能。

template<>
void processPointer<void>(void*) = delete;

template<>
void processPointer<char>(char*) = delete;

   现在当我们使用这个模板的时候就无法具现化成void*char*了,而这个功能是C++98无法做到的, 对于C++98来说实现的唯一途径就是借助于成员函数的访问权限,然后模板特化是无法在类的作用域内定义的。

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值