一、C++ 默认函数
我们知道在C++中若不显著定义以下函数,则编译器会默认提供:
- 构造函数
- 析构函数
- 拷贝构造函数
- 拷贝赋值函数,即
operator=
- 移动构造函数
C++11 为了增强对类默认函数的控制,引入了两个新关键字:
default:
告诉编译器生成函数默认的缺省版本delete:
告诉编译器不生成函数默认的缺省版本
二、default
若我们在类中自定义了上述函数之后,编译器便不再生成默认版本,如果需要我们要显式的写上其对应的默认函数版本:
#include <iostream>
using namespace std;
class Test
{
public:
Test(const int a) : m_a(a) { }
int getA() const {return m_a;}
private:
int m_a;
};
int main()
{
Test test(1);
cout << test.getA() << endl; // 1
Test test1; // 编译失败,报错: no matching function for call to ‘Test::Test()’
return 0;
}
示例定义了一个对象 test1,该对象将会使用 Test 类的无参构造函数,而该默认构造函在我们提供了自定义构造函数之后就不会再生成了,因此会报错
解决方式是:在该类中显式的提供无参构造函数
Test() { }
但这样可能让编译器失去优化功能,因此最后使用 = default;
来修饰
Test() = default;
三、delete
当我们不需要某些默认函数的时候,在C++11之前,我们经常的做法是将其声明为 private
成员函数,这样若在类外操作这些这些函数的时候,编译器便会报错
#include <iostream>
using namespace std;
class Test
{
public:
Test(const int a) : m_a(a) { }
int getA() const {return m_a;}
private:
Test(const Test&);
Test& operator= (const Test&);
int m_a;
};
int main()
{
Test test(1);
cout << test.getA() << endl; // 1
// Test test1(test);
// 报错:error: ‘Test::Test(const Test&)’ is private
// Test test1(2);
// test1 = test;
// 报错:error: ‘Test& Test::operator=(const Test&)’ is private
return 0;
}
这样虽然能够达到效果,但是不够直观和简洁。对于追求高效以及简洁来说,可以这样:
#include <iostream>
using namespace std;
class Test
{
public:
Test(const int a) : m_a(a) { }
int getA() const {return m_a;}
Test(const Test&) = delete;
Test& operator= (const Test&) = delete;
private:
int m_a;
};