C++11中为我们写类提供了更加方便的两个关键字: = default 与 = delete
下面我做了小小的测试,去初步了解这两个的作用与注意点
源代码如下:
#include <iostream>
using namespace std;
class Object_Base
{
public:
Object_Base(int a)
{
}
Object_Base() = default; //重载默认构造函数,共存
Object_Base(const Object_Base& another) //拷贝构造函数
{
this->data = another.data;
}
//Object_Base(const Object_Base&) = default; //ERROR, 拷贝构造函数不能重载
//Object_Base(const Object_Base&) = delete; //ERROR, 拷贝构造函数不能重载
Object_Base(const Object_Base&& another)
{
}
//Object_Base(const Object_Base&&) = default; //ERROR, 移动拷贝构造函数不能重载
//Object_Base(const Object_Base&&) = delete; //ERROR, 移动拷贝构造函数不能重载
Object_Base& operator=(const Object_Base& another)
{
this->data = another.data;
return *this;
}
~Object_Base() {}; //析构函数很少用到 = default,不建议将析构函数设为 = delete。 如果这样写了,那么就要自己承担后果
void Print() = delete; //delete可以用于自实现的函数中
void Print(int a) //用于验证 = delete只限于你所规定参数的接口,而不会影响其他重载的函数被删除
{
cout <<"Object_Base::Print(int a). \ta =" << a << endl;
}
//void Func() = default; //ERROR, = default 不能用在自实现的函数中
void Func1() //用于派生给派生类,让派生类去删除接口
{
cout << "Object_Base::Func1()." << endl;
}
private:
int data;
};
class Derived : public Object_Base
{
public:
Derived() = default;
Derived(int a, int b) : data2(b), Object_Base(a) {}
Derived(const Derived& another) = default;
Derived& operator=(const Derived& another)
{
Derived temp(another);
return temp;
}
~Derived()
{}
void Print() //派生类自己的Print函数
{
cout << "Derived::Print()." << endl;
}
void Func1() = delete; //删除从父类继承下来的接口
private:
int data2 = 10;
};
int main()
{
Object_Base o1(12);
Object_Base o2;
o2 = o1;
o2.Func1();
//o1.Print(); //ERROR, 提醒该接口已被删除,无法使用
o1.Print(50); //用于验证 = delete只限于一个参数的接口,而不会影响其他重载的函数被删除
Derived d1(10, 20);
Derived d2(30, 60);
//d1.Func1(); //ERROR, 提醒该接口已被删除,无法使用
d1.Print();
return 0;
}
运行结果示意图
总结:
- =delete 和 = default 通常用于“五大件”,分别是,构造函数、析构函数、赋值运算符重载、拷贝构造函数、移动拷贝构造函数、移动赋值运算符重载。
- = delete拷贝构造函数和Private拷贝构造函数的区别。=delete则是不提供实现,而设为私有则是可以通过类内的成员去访问,或者是作为友元去访问。若不想提供拷贝的功能,那么建议将拷贝构造函数,赋值运算符的重载都置为 = delete。
- = delete可以用于自实现的函数,但是也就仅仅只是不提供当前函数的实现,但是不会影响其他的同名重载函数,如上的Print()成员函数与Print(int)成员函数就是如此。
- 不建议将析构函数设为 = delete , 可以这样用,但是后果自负。(我这样测试的结果就是,导致后来无法实例化对象)
- 拷贝构造函数、移动拷贝构造函数、赋值运算符重载、移动赋值运算符重载。不支持重载,所以不允许出现自实现拷贝构造函数之后又将其设为默认( = default )或者删除( = delete )。
- = default不可以用于类内自己想要实现的函数接口, 原因是类内只提供有默认的“五大件”,没有提供其他的默认函数。
欢迎加入C++群聊:954239586