C++如何禁用类的自动赋值运算符 delete重载用法

来源:站长工具作者:马来西亚程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《C++如何禁用类的自动赋值运算符 delete重载用法》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++如何禁用类的自动赋值运算符 delete重载用法》有用,将其分享出去将是对创作者最好的鼓励。

在C++类设计中,有时候我们不希望类的对象支持自动赋值操作,比如单例类、资源独占类或者包含不可复制成员的类,这时候就需要禁用类的自动赋值运算符。C++11引入的delete关键字为这种需求提供了简洁的实现方式。

C++如何禁用类的自动赋值运算符 delete重载用法

C++自动赋值运算符的生成规则

当我们定义一个类时,如果没有显式声明拷贝赋值运算符和移动赋值运算符,编译器会在需要时自动生成这两个运算符:

  • 如果用户没有声明任何拷贝构造函数、拷贝赋值运算符、移动构造函数、移动赋值运算符、析构函数,编译器会生成默认的拷贝赋值运算符和移动赋值运算符
  • 如果用户声明了拷贝操作或者析构函数,编译器不会生成移动赋值运算符
  • 如果用户声明了移动操作,编译器不会生成拷贝赋值运算符

默认的赋值运算符会逐成员进行赋值,对于包含动态内存、文件句柄等资源的类,这种默认行为往往会导致资源重复释放或者悬空指针问题。

使用delete禁用赋值运算符

C++11之后,我们可以通过delete关键字显式禁用不需要的赋值运算符,这种方式比传统的私有声明方式更直观,也更符合现代C++的规范。

禁用拷贝赋值运算符

拷贝赋值运算符的作用是把一个已存在对象的内容赋值给另一个同类型的已存在对象,我们可以通过以下方式禁用它:

#include <iostream>
#include <string>

class ResourceClass {
private:
    std::string* data; // 独占资源指针
public:
    // 构造函数
    ResourceClass(const std::string& str) : data(new std::string(str)) {}

    // 析构函数释放资源
    ~ResourceClass() {
        delete data;
    }

    // 禁用拷贝赋值运算符
    ResourceClass& operator=(const ResourceClass& other) = delete;
};

int main() {
    ResourceClass obj1("test");
    ResourceClass obj2("demo");
    // obj2 = obj1; // 编译错误,赋值运算符已被禁用
    return 0;
}

上面的代码中,我们将拷贝赋值运算符声明为delete,当用户尝试执行obj2 = obj1这样的操作时,编译器会直接报错,阻止这种不安全的赋值行为。

禁用移动赋值运算符

移动赋值运算符是C++11新增的特性,用于将临时对象的资源转移给已存在的对象,同样可以用delete禁用:

#include <iostream>
#include <string>

class NoMoveAssign {
private:
    std::string content;
public:
    NoMoveAssign(const std::string& str) : content(str) {}

    // 禁用移动赋值运算符
    NoMoveAssign& operator=(NoMoveAssign&& other) = delete;
};

int main() {
    NoMoveAssign obj1("hello");
    NoMoveAssign obj2("world");
    // obj2 = std::move(obj1); // 编译错误,移动赋值运算符已被禁用
    return 0;
}

传统禁用方式对比

在C++11之前,开发者通常通过把赋值运算符声明为私有成员且不实现来禁用它,这种方式存在明显缺陷:

对比项传统私有声明方式delete关键字方式
可读性不直观,需要额外注释说明意图语义明确,直接表达禁用意图
错误提示友元类或者成员函数内调用时才会报错,提示不友好编译阶段直接报错,错误提示清晰
适用场景仅C++11之前版本可用C++11及之后版本推荐

注意事项

  • delete关键字可以用于禁用任何函数,不仅仅是赋值运算符,比如也可以禁用默认构造函数、拷贝构造函数等
  • 如果同时禁用了拷贝赋值和移动赋值,那么类的对象将完全不支持赋值操作
  • delete声明必须放在函数的声明部分,不能和函数定义同时出现
  • 对于单例类,通常会同时禁用拷贝构造、拷贝赋值、移动构造、移动赋值,确保单例的唯一性

通过合理使用delete关键字禁用不需要的赋值运算符,可以让类的设计更严谨,避免很多因为默认赋值行为带来的潜在问题,是C++类设计中非常实用的技巧。

C++赋值运算符delete运算符重载类设计修改时间:2026-06-13 14:03:31

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。