2026/6/20 11:23:26
网站建设
项目流程
网站wordpress是什么意思,高端网站教建设,深圳产品设计公司排名前十强,软件开发模型主要有哪些你想弄明白C中 delete和 default这两个语法的区别与用法#xff0c;它们是C11引入的核心特性#xff0c;主要用于精准控制类的特殊成员函数#xff08;如构造函数、拷贝构造、赋值运算符等#xff09;。我会用通俗的语言实战示例#xff0c;讲清两者的核心用途、区别和使用…你想弄明白C中 delete和 default这两个语法的区别与用法它们是C11引入的核心特性主要用于精准控制类的特殊成员函数如构造函数、拷贝构造、赋值运算符等。我会用通俗的语言实战示例讲清两者的核心用途、区别和使用场景结合你之前接触的单例模式、类模板等场景加深理解。一、核心定义先立概念语法核心作用通俗理解 default显式要求编译器生成默认版本的特殊成员函数如默认构造、拷贝构造“编译器按你的默认规则帮我生成这个函数” delete显式禁用某个函数让编译器拒绝生成/禁用调用“编译器这个函数我不用禁止任何人调用”二、 default显式生成默认函数1. 为什么需要 defaultC编译器会为类隐式生成默认构造、拷贝构造、赋值运算符、析构函数等特殊成员函数但如果类中自定义了某些函数如带参数的构造函数编译器就会停止生成默认版本。 default可以强制编译器重新生成这些默认函数既保留自定义逻辑又不丢失默认行为。2. 实战示例#includeiostreamusingnamespacestd;classPerson{private:string name;intage;public:// 自定义带参数的构造函数编译器不再生成默认构造Person(string n,inta):name(n),age(a){}// 显式要求编译器生成默认构造函数 defaultPerson()default;// 显式要求编译器生成默认拷贝构造函数Person(constPerson)default;// 显式要求编译器生成默认赋值运算符Personoperator(constPerson)default;// 显式要求编译器生成默认析构函数~Person()default;voidshow(){coutname: name, age: ageendl;}};intmain(){// 调用默认构造函数因 default生效Person p1;p1.show();// 输出name: , age: 0// 调用自定义构造函数Personp2(Tom,18);p2.show();// 输出name: Tom, age: 18// 调用默认拷贝构造函数Person p3p2;p3.show();// 输出name: Tom, age: 18// 调用默认赋值运算符p1p2;p1.show();// 输出name: Tom, age: 18return0;}3. 关键细节 default只能用于编译器可自动生成的特殊成员函数默认构造、拷贝构造、移动构造、赋值运算符、析构函数等不能用于普通函数用 default生成的函数比手动写的“空函数”更高效编译器会优化为原生代码示例中如果不加Person() default;Person p1;会编译报错编译器未生成默认构造。三、 delete显式禁用函数1. 为什么需要 delete用于禁止某些函数的调用或生成最常见场景是禁用拷贝构造/赋值运算符如单例模式保证实例唯一禁用特定类型的函数重载如禁止int隐式转换为double禁用编译器自动生成的特殊成员函数。2. 实战场景1单例模式禁用拷贝/赋值这是你之前接触的场景用 delete保证类实例唯一#includeiostreamusingnamespacestd;classSingleton{private:staticSingleton instance;// 私有构造函数禁止外部创建Singleton(){coutSingleton创建endl;}// 禁用拷贝构造 deleteSingleton(constSingleton)delete;// 禁用赋值运算符 deleteSingletonoperator(constSingleton)delete;public:staticSingletongetInstance(){returninstance;}};Singleton Singleton::instance;intmain(){Singletons1Singleton::getInstance();// 以下代码编译报错因拷贝/赋值被禁用// Singleton s2 s1;// Singleton s3;// s3 s1;return0;}3. 实战场景2禁用特定函数重载#includeiostreamusingnamespacestd;// 函数模板计算两个数的和templatetypenameTTadd(T a,T b){returnab;}// 禁用int版本的add deletetemplateintaddint(inta,intb)delete;intmain(){// 正常调用double版本coutadd(3.14,5.67)endl;// 输出8.81// 编译报错int版本被delete// cout add(1, 2) endl;return0;}4. 关键细节 delete可用于任意函数特殊成员函数、普通函数、模板函数比 default适用范围广被 delete的函数即使声明了也无法调用编译期直接报错C03中禁用拷贝构造的方式是“声明为private且不实现”C11后推荐用 delete更清晰、编译期检测。四、 defaultvs delete核心区别维度 default delete核心目的让编译器生成默认版本的函数让编译器禁用某个函数拒绝生成/调用适用范围仅特殊成员函数编译器可自动生成的任意函数特殊成员、普通函数、模板函数编译行为生成函数代码允许调用拒绝生成函数代码调用时报错典型场景自定义构造后恢复默认构造、优化默认函数单例禁用拷贝、禁止特定类型的函数调用五、常见坑点与最佳实践1. 坑点1误用 default/ delete// 错误普通函数不能用 defaultvoidfunc()default;// 错误析构函数delete后类无法实例化对象销毁时需要析构~Person()delete;Person p;// 编译报错2. 坑点2默认函数的生成规则如果类中自定义了析构函数编译器不再自动生成移动构造/移动赋值如果用 delete禁用了拷贝构造编译器也不会自动生成移动构造建议要么显式用 default指定要么显式用 delete禁用避免依赖编译器的隐式规则。3. 最佳实践单例模式必用 delete禁用拷贝构造和赋值运算符需要默认构造但又自定义了带参构造用 default恢复默认构造禁止隐式类型转换用 delete禁用特定重载如add(int)优化性能对编译器自动生成的函数用 default比手动写空函数高效。总结 default显式要求编译器生成默认版本的特殊成员函数解决“自定义构造后丢失默认函数”的问题且更高效 delete显式禁用函数核心用于单例模式禁用拷贝、禁止特定函数调用是C11后替代“私有不实现”的最佳方式两者都是C11的语法糖核心价值是精准控制类的函数生成规则让代码更清晰、更符合预期记忆口诀default是“要默认”delete是“要禁用”。这两个语法在现代C尤其是嵌入式、高性能开发中非常常用掌握它们能让你写出更规范、更高效的类设计代码。