谈谈C++11中的默认和删除函数(defaulted and deleted functions)及其用途。
参考回答
C++11 引入了默认和删除函数(defaulted and deleted functions),这使得类的设计更加灵活和精确。默认函数允许编译器生成某些成员函数的默认实现,而删除函数则允许显式禁用某些成员函数的生成或调用。这些特性有助于提高代码的安全性、可维护性和明确性。
- 默认函数(defaulted functions):使用
= default
语法显式请求编译器生成默认实现。 - 删除函数(deleted functions):使用
= delete
语法显式禁止某些函数的调用。
详细讲解与拓展
1. 默认函数(defaulted functions)
在某些情况下,我们可能希望让编译器自动生成特定的特殊成员函数(如构造函数、拷贝构造函数、赋值操作符等),但也希望显式地指定这些函数,而不是让编译器隐式生成。这时可以使用 = default
来请求编译器生成默认实现。
示例:默认构造函数
在这个例子中,MyClass
类显式使用 = default
请求编译器生成默认构造函数。这使得类在没有定义任何构造函数时,仍然能够正常工作,并且不需要显式编写构造函数。
示例:默认拷贝构造函数
在这个例子中,MyClass
类显式声明了默认的拷贝构造函数。这样,当我们创建 obj2
时,编译器会使用默认的拷贝构造函数将 obj1
的内容拷贝到 obj2
。
2. 删除函数(deleted functions)
删除函数通过 = delete
显式禁用某些成员函数的生成或调用。常见的用法是禁止拷贝构造、赋值操作符等,防止不希望的操作。例如,当我们不希望对象被拷贝或赋值时,可以删除相关的函数。
示例:删除拷贝构造函数
在这个例子中,我们通过 = delete
删除了 MyClass
的拷贝构造函数,因此不能再通过拷贝构造函数创建新对象。如果尝试进行拷贝,会导致编译错误。
示例:删除赋值操作符
在这个例子中,operator=
被删除,因此 obj1
和 obj2
不能进行赋值操作。如果尝试赋值,会导致编译错误。
3. 使用删除函数禁用特定操作
除了拷贝构造和赋值操作符,删除函数还可以用于禁用其他不必要或不安全的操作。例如,禁止移动构造函数或禁止特定类型的函数调用。
示例:禁止移动构造函数
在这个例子中,我们删除了移动构造函数,这防止了通过 std::move
对象的移动操作,从而避免了可能的不安全操作。
4. 默认和删除函数的实际应用
- 禁止拷贝:当一个类的对象不应被拷贝时,可以删除拷贝构造函数和赋值操作符。例如,
std::unique_ptr
类就禁止了拷贝操作,只允许移动操作。 - 显式指定构造行为:使用默认构造函数和默认拷贝构造函数,开发者可以显式要求编译器生成相应的函数,而不是依赖于编译器的默认行为。
- 强制类型安全:删除不必要的操作,如移动构造、拷贝构造,可以避免潜在的错误,增强代码的安全性。
总结
C++11 中的默认和删除函数(= default
和 = delete
)是控制类成员函数行为的重要工具。通过使用 = default
,我们可以显式请求编译器生成默认实现的特殊成员函数;通过使用 = delete
,我们可以显式禁止某些不希望的操作(如拷贝、赋值或移动操作)。这些特性使得类的设计更加灵活、安全,帮助开发者更好地控制对象的生命周期和行为。