答案:= default 和 = delete 用于显式控制C++特殊成员函数的生成与使用。前者强制编译器生成默认实现,适用于需编译器自动生成函数且信任其行为的场景;后者禁止函数使用,防止拷贝、移动或隐式转换等不合法操作。它们提升代码安全性与清晰度,支持“零法则”,确保资源管理正确,避免运行时错误。

C++中,
= default
= delete
= default
= delete
在C++类中,
= default
= delete
= default
= delete
= default
= default
class MyClass {
public:
int value;
// 显式声明了带参数构造函数
MyClass(int v) : value(v) {}
// 强制编译器生成默认构造函数
MyClass() = default;
// 也可以用于析构函数、拷贝/移动构造函数和赋值运算符
// MyClass(const MyClass&) = default;
// MyClass& operator=(const MyClass&) = default;
// ~MyClass() = default;
};这样做的优点是,你明确告诉了编译器你的意图,并且利用了编译器在优化和正确性方面的优势。它比空的大括号实现
MyClass() {}= delete
= delete
立即学习“C++免费学习笔记(深入)”;
防止对象拷贝: 当你的类管理着独占资源(如文件句柄、网络连接),或者拷贝语义没有意义时,你可能希望禁止拷贝构造函数和拷贝赋值运算符。
class NonCopyable {
public:
NonCopyable() = default;
// 显式删除拷贝构造函数和拷贝赋值运算符
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
// 如果需要,可以允许移动
NonCopyable(NonCopyable&&) = default;
NonCopyable& operator=(NonCopyable&&) = default;
};尝试拷贝
NonCopyable
防止隐式类型转换: 你可以删除某个特定参数类型的构造函数,以防止不希望的隐式转换。
class MyNumber {
public:
MyNumber(int i) : val(i) {}
// 禁止从double隐式构造
MyNumber(double d) = delete;
private:
int val;
};
MyNumber n1(10); // OK
// MyNumber n2(10.5); // 编译错误,因为double构造函数被删除了强制堆分配: 如果你希望对象只能在堆上创建,可以删除其
operator new
operator delete
= delete
这些机制让C++的类设计变得更加严谨和安全。
= default
在我看来,
= default
= default
当你提供了自定义构造函数,但仍需要默认构造函数时: 这是一个经典场景。一旦你写了任何一个构造函数,编译器就不会再自动生成默认构造函数。如果你的类成员都是可以默认构造的,并且你确实需要一个无参数的构造函数来创建对象,那么
MyClass() = default;
MyClass() {}当你需要强制编译器生成特定的特殊成员函数时: 比如,你的类可能包含一些复杂的数据成员,它们的拷贝/移动语义由它们自身的类定义。如果你想让你的类也拥有同样的默认拷贝/移动行为,但又不想自己手动去写成员逐个拷贝/移动的逻辑(这不仅冗余,而且容易出错),那么
= default
std::string
MyClass(const MyClass&) = default;
= default
遵循“零法则”的哲学: C++社区有一种“零法则”的说法,即如果你的类不需要管理资源(例如,不拥有原始指针,不直接进行内存分配),那么你可能根本不需要自定义任何特殊成员函数,让编译器自动生成所有这些函数是最好的选择。在这种情况下,如果你出于某种原因(比如为了代码清晰度或为了防止未来的维护者误解)想显式地列出它们,那么
= default
使用
= default
= delete
= delete
资源独占性与所有权语义: 很多时候,一个类代表着某种独占资源的所有权,比如文件句柄、互斥锁、网络套接字或者智能指针(如
std::unique_ptr
= delete
例如,一个管理文件描述符的类:
#include <string>
#include <stdexcept>
#include <unistd.h> // For open, close
#include <fcntl.h> // For O_RDWR, etc.
class FileHandle {
private:
int fd;
public:
FileHandle(const std::string& filename, int flags) {
fd = open(filename.c_str(), flags);
if (fd == -1) throw std::runtime_error("Failed to open file");
}
~FileHandle() {
if (fd != -1) close(fd);
}
// 禁止拷贝
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
// 允许移动,转移所有权
FileHandle(FileHandle&& other) noexcept : fd(other.fd) {
other.fd = -1; // 转移所有权
}
FileHandle& operator=(FileHandle&& other) noexcept {
if (this != &other) {
if (fd != -1) close(fd); // 释放自己的资源
fd = other.fd;
other.fd = -1;
}
return *this;
}
};这里,
= delete
FileHandle
防止逻辑不一致或无意义的操作: 有些类可能设计为单例模式,或者其内部状态是全局唯一的,拷贝
以上就是C++如何在类中使用默认和删除函数的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号