如果你实现了某个类给其他程序猿使用,但是不想让他使用某个特定函数,那我们可以直接不声明该函数即可。但是如果这个函数是编译器自动生成的,例如默认赋值函数,那我们又应该怎么做呢?

C++98中的做法是将该函数声明为private权限,这样就阻止了外部直接调用它,然后我们也不去定义它,这样当该类的成员函数误调用该函数时,会提示链接错误。例如:

class Test {
public:
    void Fix(Test& t) {
        Test t1;
        t1 = t;  //编译报错,使用未定义函数
    }
private:
    Test& operator=(const Test& t);//只声明,不定义
};

Test t1,t2;
t1 = t2;   //编译报错,private权限问题

但是C++11为我们新增了一个关键字,可以很简单的解决这个问题,那就是delete关键字。上述同样的代码,只需要在赋值函数后面加上delete即可。

class Test {
public:
    void Fix(Test& t) {
        Test t1;
        t1 = t;  //编译报错,使用delete函数
    }

    Test& operator=(const Test& t) = delete;//只声明,不定义
};

Test t1,t2;
t1 = t2;   //编译报错,使用delete函数

使用delete的另一个好处就是,delete不仅可以可以修饰成员函数,普通全局函数也可以使用delete,特别是函数重载场景时,delete还是非常好用的,因为即使这个函数虽然被删除了,但它还是程序的一部份,在重载决议时,仍然会纳入考量,特别时最后匹配到删除函数时,将提示编译错。

//无delete场景
bool isLove(int);

isLove(12); //匹配到isLove(int)
isLove(false);//false隐式转换为int,匹配到isLove(int)
isLove(3.5);//double隐式转换为int,匹配到isLove(int)


//使用delete场景
bool isLove(int);
bool isLove(bool) = delete;
bool isLove(double) = delete;

isLove(12); //匹配到isLove(int)
isLove(false);//匹配到isLove(bool),因其为删除函数,编译报错
isLove(3.5); //匹配到isLove(double),因其为删除函数,编译报错

下面的一个场景,你将不得不使用delete,即删除某个模板函数(成员函数或全局函数)的某个类型的具现函数,这个只能借助delete关键字:

//全局函数
template<class T>
void TestFunc(T* ptr);

template<>
void TestFunc<void>(void*) = delete;   //删除该模板的void类型具现

template<>
void TestFunc<char>(char*) = delete;   //删除该模板的char类型具现


//成员函数,类内类外均可删除
class TestClass{
public:
    template<class T>
    void TestFunc2(T* ptr);
    
    template<>
    void TestFunc2<void>(void*) = delete;   //类内删除该模板的void类型具现
};

template<>
void TestClass::TestFunc2<char>(char*) = delete;   //类外删除该模板的char类型具现