Modern Effective C++ Item 11:优先考虑使用deleted函数而非使用未定义的私有声明

C++98 方法:private

C++98 将特殊成员函数(如拷贝构造函数和拷贝赋值运算符)声明为私有且不定义。这种方法可以防止客户端调用这些函数,但如果在成员函数或友元函数中调用这些函数,会在链接时引发错误。C++11 使用 = delete 将这些函数标记为删除的函数。删除的函数不能以任何方式被调用,即使在成员函数或友元函数中调用也会在编译时失败。这比 C++98 的方法更安全,因为错误在编译阶段就能捕获。删除的函数通常声明为 public 而不是 private。这是因为当客户端代码试图调用成员函数时,编译器会先检查访问性,再检查删除状态。如果函数是 private 的,编译器可能会只报告访问性错误,而不会提到函数已被删除。

cpp 复制代码
template <class charT, class traits = char_traits<charT> >
class basic_ios : public ios_base {
public:
    ...
private:
    basic_ios(const basic_ios& );           // not defined
    basic_ios& operator=(const basic_ios&); // not defined
};
C++11 方法 =delete

使用=delete可以禁止特定类型的函数调用,可以禁止特定类型的模板实例化,类内的模板函数特化,如果类内有一个模板函数,使用 = delete 可以在类外删除特定的模板实例。这是因为在类内不能给特化的成员模板函数指定不同的访问级别,而在类外删除这些函数不会有问题。

cpp 复制代码
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;
};

禁止特定类型的函数调用

cpp 复制代码
bool isLucky(int number);       // 原始版本
bool isLucky(char) = delete;    // 拒绝 char
bool isLucky(bool) = delete;    // 拒绝 bool
bool isLucky(double) = delete;  // 拒绝 float 和 double

禁止特定类型的模板实例化

cpp 复制代码
template<typename T>
void processPointer(T* ptr);
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;
template<>
void processPointer<const volatile void>(const volatile void*) = delete;
template<>
void processPointer<const volatile char>(const volatile char*) = delete;
template<>
void processPointer<wchar_t>(wchar_t*) = delete;
template<>
void processPointer<char16_t>(char16_t*) = delete;
template<>
void processPointer<char32_t>(char32_t*) = delete;

类内的模板函数特化

cpp 复制代码
class Widget {
public:
    template<typename T>
    void processPointer(T* ptr){}
};
template<>
void Widget::processPointer<void>(void*) = delete;
相关推荐
legend_jz20 分钟前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
嘿BRE30 分钟前
【C++】几个基本容器的模拟实现(string,vector,list,stack,queue,priority_queue)
c++
ö Constancy1 小时前
c++ 笔记
开发语言·c++
fengbizhe1 小时前
笔试-笔记2
c++·笔记
徐霞客3202 小时前
Qt入门1——认识Qt的几个常用头文件和常用函数
开发语言·c++·笔记·qt
fpcc2 小时前
redis6.0之后的多线程版本的问题
c++·redis
螺旋天光极锐斩空闪壹式!2 小时前
自制游戏:监狱逃亡
c++·游戏
工业3D_大熊3 小时前
3D可视化引擎HOOPS Luminate场景图详解:形状的创建、销毁与管理
java·c++·3d·docker·c#·制造·数据可视化
流星白龙3 小时前
【C++习题】10.反转字符串中的单词 lll
开发语言·c++