《Modern Effective C++》读书笔记之条款十一:优先选用删除函数,而非private未定义函数

本文讨论了在C++中如何阻止其他程序员使用某些函数,对比了使用private和delete关键字的区别。删除函数比private更严谨,无法通过任何方式调用,且通常应声明为public以提供更好的错误信息。此外,删除函数还可用于禁止无意义的模板实例化和特定类型的函数调用。因此,推荐优先选择使用删除函数。
摘要由CSDN通过智能技术生成

优先选用删除函数,而非private未定义函数

当我们想要阻止其他程序员使用某个函数时,只需要不声明该函数即可,但是C++有时候会替你声明函数,比如自动生成的成员函数,本文中目前只考虑拷贝构造函数和赋值运算符函数。C++11以前我们的做法是将这些函数声明为private,并且不去定义它们。
举例来讲,在C++标准库中输入输出流库继承于basic_ios,对输入流和输出流进行复制是不可取的,C++98中的basic_ios的声明如下:

template <class charT, class traits = char_traits<charT> >
class basic_ios : public ios_base {
public:
	// ...
private:
	basic_ios(const basic_ios&); // 不可复制
	basic_ios& operator=(const basic_ios&); // 不可赋值
};

在C++11中,有了删除函数,使用delete可以使它们标识为删除函数,我们可以将上述代码改为:

template <class charT, class traits = char_traits<charT> >
class basic_ios : public ios_base {
public:
	// ...
	basic_ios(const basic_ios&) = delete;
	basic_ios& operator=(const basic_ios&) = delete;
	// ...
};

使用delete关键字和将函数声明为private看起来只是不同风格的选择,但实际上是有区别的。

  1. 使用delete删除的函数无法通过任何方法调用,即使是成员函数或友元函数中的代码也是无法调用的。相对于private的做法来讲,这是一种改进。
  2. 删除函数往往被声明为public。这样做的好处是,当客户代码尝试调用某个成员函数时,C++会先校验其可访问性,后校验删除状态。这么一来,当客户代码尝试调用某个private函数,编译器只会提示该函数为private。所以把新的delete函数声明为public会得到更好的错误信息。
  3. 任何函数都可以成为删除函数,但是只有成员函数才能被声明为private。

举例来讲,如果我们有一个函数bool isLucky(int number);C++中很多类型可以隐式转换到int中,所以会出现以下无意义的代码调用

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

当我们想要阻止这样的调用的时候,我们可以通过delete关键字来删除对应的重载版本

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

这样再出现上述调用的时候,编译器会提示上述函数已经删除,无法调用。

  1. 删除函数还可以阻止那些不应该进行的模板实现。

举例来讲,如果你需要一个和内建指针协作的模板

template <typename T>
void processPointer(T* ptr) {
	// ...
}

而指针的类型中有两个异类,一个是void*,因为无法对它实现自增自减等操作,一个是char*,它是C风格的字符串,而不是指向单个字符的指针。这时候我们可以通过删除函数来阻止对这两种类型的模板实现,而这一点是private无法做到的。

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

总结:

  1. 优先选用删除函数,而非private未定义的函数
  2. 任何函数都可以被删除,包括非成员函数和模板函数

参考: 《Modern Effective C++》第五版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值