天天看点

C++禁止使用拷贝构造函数和赋值运算符方法

1.将拷贝构造函数和赋值运算符声明为私有,并不予实现

class Uncopyable  
{  
private:  
    Uncopyable(const Uncopyable &); // 阻止copying  
    Uncopyable &operator=(const Uncopyable &);  
};      

2.使用delete

C++11 中,可在想要 “禁止使用” 的特殊成员函数声明后加 “= delete”

class Uncopyable  
{  

    Uncopyable(const Uncopyable &) =delete; // 阻止copying  
    Uncopyable &operator=(const Uncopyable &)=delete;  
};      

C++11 中,delete 关键字可用于任何函数,不仅仅局限于类成员函数

在函数重载中,可用 delete 来滤掉一些函数的形参类型,如下:

bool IsLucky(int number);        // original function
bool IsLucky(char) = delete;     // reject chars
bool IsLucky(bool) = delete;     // reject bools
bool IsLucky(double) = delete;   // reject doubles and floats      

这样在调用 IsLucky 函数时,如果参数类型不对,则会出现错误提示

if (IsLucky('a')) …     // error !    call to deleted function
if (IsLucky(true)) …    // error !
if (IsLucky(3.5)) …     // error !      

在模板特例化中,也可以用 delete 来过滤一些特定的形参类型。

例如,Widget 类中声明了一个模板函数,当进行模板特化时,要求禁止参数为 void* 的函数调用。

如果按照 C++98 的 “私有不实现“ 思路,应该是将特例化的函数声明为私有型,如下所示:

class Widget {
public:
    template<typename T>
    void ProcessPointer(T* ptr) { … }
private:
    template<>             
    void ProcessPointer<void>(void*);    // error!
};      

问题是,模板特化应该被写在命名空间域 (namespace scope),而不是类域 (class scope),因此,该方法会报错。

class Widget {
public:
    template<typename T>
    void ProcessPointer(T* ptr) { … }
};

template<> 
void Widget::ProcessPointer<void>(void*) = delete; // still public, but deleted