在 C++ 中,delete
和 default
是两个用于控制类成员函数行为的关键字。它们通常用于显式地管理类的特殊成员函数(如构造函数、析构函数、拷贝构造函数、赋值运算符等)的生成和使用。
1. delete
关键字的作用
delete
用于显式地禁用类的某些成员函数或转换函数,使其不能被调用或使用。
(1)禁用特殊成员函数
- 通过将特殊成员函数标记为
delete
,可以阻止编译器自动生成该函数。 - 常见的用途包括禁用拷贝构造函数、赋值运算符等。
示例:禁用拷贝构造函数和赋值运算符
class NonCopyable {
public:
NonCopyable() = default;
// 禁用拷贝构造函数
NonCopyable(const NonCopyable&) = delete;
// 禁用赋值运算符
NonCopyable& operator=(const NonCopyable&) = delete;
};
int main() {
NonCopyable obj1;
// NonCopyable obj2 = obj1; // 错误:拷贝构造函数被禁用
// obj2 = obj1; // 错误:赋值运算符被禁用
return 0;
}
(2)禁用转换函数
- 通过将转换函数标记为
delete
,可以阻止某些隐式类型转换。
示例:禁用从 int
到 MyClass
的隐式转换
class MyClass {
public:
MyClass(int value) {}
// 禁用从 double 到 MyClass 的隐式转换
MyClass(double) = delete;
};
int main() {
MyClass obj1(10); // 合法
// MyClass obj2(10.5); // 错误:从 double 到 MyClass 的转换被禁用
return 0;
}
(3)禁用某些函数重载
- 通过将某些函数重载标记为
delete
,可以阻止调用特定的函数版本。
示例:禁用特定参数类型的函数重载
void func(int value) {}
void func(double) = delete; // 禁用 double 版本的 func
int main() {
func(10); // 合法
// func(10.5); // 错误:double 版本的 func 被禁用
return 0;
}
2. default
关键字的作用
default
用于显式地要求编译器生成默认的特殊成员函数。
(1)生成默认的特殊成员函数
- 通过将特殊成员函数标记为
default
,可以显式地要求编译器生成默认实现。 - 常见的用途包括生成默认构造函数、析构函数、拷贝构造函数、赋值运算符等。
示例:显式生成默认构造函数和析构函数
class MyClass {
public:
MyClass() = default; // 显式生成默认构造函数
~MyClass() = default; // 显式生成默认析构函数
};
(2)恢复被抑制的默认函数
- 如果类的某些行为(如定义了移动构造函数)导致编译器不再自动生成默认的特殊成员函数,可以使用
default
恢复默认行为。
示例:恢复默认的拷贝构造函数
class MyClass {
public:
MyClass() = default;
// 定义移动构造函数
MyClass(MyClass&&) {}
// 恢复默认的拷贝构造函数
MyClass(const MyClass&) = default;
};
3. delete
和 default
的对比
特性 | delete | default |
---|---|---|
作用 | 禁用某些成员函数或转换函数 | 显式生成默认的特殊成员函数 |
适用场景 | 禁用拷贝、赋值、转换等 | 恢复或显式生成默认函数 |
常见用途 | 禁用拷贝构造函数、赋值运算符等 | 生成默认构造函数、析构函数等 |
4. 使用场景总结
(1)delete
的使用场景
- 禁用拷贝构造函数和赋值运算符,实现不可拷贝的类。
- 禁用某些隐式类型转换。
- 禁用特定的函数重载。
(2)default
的使用场景
- 显式生成默认构造函数、析构函数等。
- 恢复被抑制的默认特殊成员函数。
5. 示例代码
class MyClass {
public:
MyClass() = default; // 显式生成默认构造函数
MyClass(const MyClass&) = delete; // 禁用拷贝构造函数
MyClass& operator=(const MyClass&) = delete; // 禁用赋值运算符
// 显式生成默认析构函数
~MyClass() = default;
};
int main() {
MyClass obj1;
// MyClass obj2 = obj1; // 错误:拷贝构造函数被禁用
// obj2 = obj1; // 错误:赋值运算符被禁用
return 0;
}
6. 总结
delete
:用于禁用某些成员函数或转换函数,防止不期望的行为。default
:用于显式生成默认的特殊成员函数,确保类的行为符合预期。
在面试中,理解 delete
和 default
的作用并能够举例说明其使用场景是非常重要的。
THE END
暂无评论内容