条款4:非必要不提供default constructor

条款4:非必要不提供 default constructor 摘要:本文探讨了C++中默认构造函数的使用原则。核心观点是"非必要不提供默认构造函数",反对在对象无法合理初始化时强制提供无参构造函数。文章指出,硬性提供默认构造会导致对象状态无效、破坏类不变量,增加使用复杂度。正确做法是通过有参构造函数强制完整初始化。对于没有默认构造的类,推荐使用std::vector逐个构造而非数组。仅在值类型有空状态、容器需求或框架集成等必要情况下才应提供默认构造。这一原则体现了RAII思想,确保对象从创建起就处于完整可用状态。 阅读详情

**
印象笔记:
**

default constructor 也就是说不给任何自变量就可调用者。Constructors用来将对象初始化,所以default constructors的意思是在没有任何外来信息的情况将对象初始化。

数值之类的对象可以被合理地初始化为0或一个无意义值。其他诸如指针之类的对象亦可以被合理地初始化为null或无意义值。数据结构如linked lists,maps等可以被初始化为空容器。
但并非所有对象都落入这样的分类。有许多对象,如果没有外来信息,就没有办法执行一个完全的初始化动作。例如,某个通信簿字段的class如果没有获得外界指定的人名,产生出来的对象将毫无意义。在某些公司,所有仪器设备都必须有个识别号码,如果没有获得适当的ID号码,将毫无意义。

考虑以下缺乏default constructor的class:

class EquipmentPrice{
    public:
        EquipmentPrice(int IDNumber);
}

可能在以下情况下出现问题。
1)在产生对象数组的时候,一般而言没有任何方法可以为数组中的对象指定constructor自变量。

EquipmentPiece bestPieces[10]; // 错误!没有正确调用
// EquipmentPiece 构造函数
EquipmentPiece *bestPieces =
new EquipmentPiece[10]; // 错误!与上面的问题一样

解决方法:

a.使用非堆内存non-heap数组


int ID1, ID2, ID3, ..., ID10; // 存储设备ID号的
// 变量
...
EquipmentPiece bestPieces[] = { // 正确, 提供了构造函数的参数
 EquipmentPiece(ID1), 
 EquipmentPiece(ID2),
 EquipmentPiece(ID3),
 ...,
 EquipmentPiece(ID10)
};

b.使用“指针数组”而非“对象数组“

typedef EquipmentPiece* PEP; // PEP 指针指向
//一个EquipmentPiece对象
PEP bestPieces[10]; // 正确, 没有调用构造函数
PEP *bestPieces = new PEP[10]; // 也正确

此法有两个缺点:
**必须记得将此数组所指的所有对象删除;
**需要的内存总量比较大,因为需要一些空间来放置指针,还需要一些空间来放置EquipmentPiece objects。

“过度使用内存”这个问题可以通过先为数组分配raw memory,然后使用“placement new”在这块内存上构造EquipmentPiece objects。
但无论如何,还是必须供给constructor一个自变量,作为每个EquipmentPiece objects的初值。这个“由指针构成数组”的方法只是允许你在“缺乏default constructor”的情况下仍能产生对象数组。
placement new的缺点是在数组内的对象结束生命时,还需要手动调用其destructors,最后还得以调用operator delete[]的方式释放raw memory。

2)class缺少default constructors带来的第二个缺点是:将不适用于许多template-based container classes。
对于templates而言,被实例化的目标类型必须得有一个default constructor。因为在那些templates内几乎总是会产生一个以“template类型参数”作为类型而架构起来的数组。
大部分情况下,谨慎设计template可以消除对default constructor的需求。但大部分都不兼容于(不够严谨的)template。

最后一个考虑点,virtual base classes。virtual base class constructors的自变量必须由欲产生的对象的派生层次最深的class提供。于是要求所有的派生类都要为这个virtual base class的constructor提供自变量。这是设计者不期望也不欣赏的要求。

由于“缺乏default constructor”带来的束缚,有人便认为所有classes都应该提供default constructor–甚至即使其default constructor没有足够信息将对象做完整的初始化。依照这样的哲学,Equipment可能会被修改如下:

class EquipmentPiece {
    public:
        EquipmentPiece( int IDNumber = UNSPECIFIED);
  ...
    private:
        static const int UNSPECIFIED; // ID值不确定。
};

这不再保证一个EquipmentPiece object的所有字段都是富有意义的初值,将会造成大部分member function必须检查字段是否存在。通常,许多编译器选择的解决方法是:什么都不做,仅抛出一个exception,或是调用某函数将程序结束掉。这样的事情一旦发生,我们很难认为软件的整体质量因为画蛇添足地加上了一个default constructor而获得提升。

如果class constructor可以确保对象的所有字段都会被正确地初始化,上述的时间代价、空间代价便都可以免除。如果default constructor无法提供这种保证,那么最好避免让default constructor出现。虽然这可能会对class的使用方式带来某种限制,但同时带来一种保证:当你真的使用了这样的class,你可以预期它们产生的对象会被完全地初始化,实现上亦富有效率。

深入解析以太网接口中的BOB Smith电路设计 本文深入解析以太网接口中的BOB Smith电路设计,详细介绍了其在共模噪声抑制、浪涌防护和EMI优化中的关键作用。通过实际案例和设计要点,帮助工程师正确选择75Ω电阻和高压电容等元件,优化PCB布局,解决电压型与电流型PHY的设计差异,以及千兆与百兆以太网的特殊考量。 阅读详情

相关推荐

信贷审批中的那些坑:从零开始搭建风控策略体系的5个关键步骤

本文深入探讨了信贷审批中的风控策略体系搭建,从数据陷阱识别、规则冲突诊断到反欺诈攻防,提供了5个关键步骤的实战指南。重点解析了如何通过特征工程、决策树优化和模型可解释性技术,构建动态平衡的风控体系,有效降低逾期风险并提升审批效率。

weixin_29253711的博客 413

【More Effective C++ 条款4】非必要不提供default constructor

1)default constructor:在没有任何外来信息的情况下将对象初始化2)但是有些对象如果没有外来信息,就没有办法完成初始化动作,那么这些对象,就没有必要提供default constructor3)如果一个类缺乏default constructor,那么使用这个类的时候会存在一定的限制限制1:产生数组的时候,没有任何一个方法可以为数组中的对象指定constructor自变...

Y先森0.0 267

ANSYS Workbench瞬态结构分析(1)时域分析

本文围绕瞬态结构分析展开。首先阐释其概念与理论基础,涵盖控制方程及数值求解方法。接着详述在 ANSYS Workbench 中进行瞬态分析的操作流程,以音叉为例,介绍从创建分析系统、材料定义、几何处理与网格划分,到边界条件与载荷设置、求解器设置及结果后处理的各步骤。之后对分析结果进行探讨,并针对计算不收敛、计算时间过长等常见问题给出调试技巧,旨在为读者提供全面的瞬态结构分析知识与实践指导。

qq_58675332的博客 6530

【C++ Basics】非必要不提供default constructor

如果 class constructors 可以确保对象所有字段都会被正确初始化,即可以免除为测试行为付出的时间代价、为测试代码付出的空间代价,因为其可执行文件和程序库都变大了。 如果无法保证,最好避免 default constructor 出现。

Zoey的博客 177

Unity UI适配实战:从Canvas Scaler到主流游戏适配方案解析

本文深入解析Unity UI适配的核心技术,重点介绍Canvas Scaler组件的关键参数如Reference Resolution和Screen Match Mode,并提供主流游戏适配方案实战分析。通过九宫格拉伸、动态调整等技巧,帮助开发者解决多设备适配难题,提升游戏UI在不同分辨率下的表现。

weixin_29001419的博客 972

104报文解析工具

可选择包含报文的文本文件或日志文件进行解析,可选择按条数范围或时间范围,输出结果可以在报文解析显示区,也可以输出到文件。可以对文本内容的报文文件进行高级分析,包括遥信遥测等通讯数据的具体信息,通讯帧的统计,通讯次数的统计,各种错误的分析,报文的定位功能,传输的文件具体内容等。输入完成后点击工具栏的解析报文按钮或使用右键菜单的解析就可以对报文进行解析。在报文输入区输入待解析报文并解析后,解析结果就显示在报文解析显示区和报文定位展示区及报文定位条目区。当有多条报文解析后,可以通过报文列表树具体定位某条报文。

XZHOUMIN的博客 5949

4.非必要不提供default constructor

注:不必要提供default constructor不代表没有constructor。 缺乏default constructor可能产生的问题: 1.无法产生数组 Class T[10];  //错误的,无法调用default constructor    一般的解决办法是使用指针数组,即10个类对象的指针。 Class *T[10]; Class *T = new

yuqtj的专栏 527

Qwen3-Omni-30B-A3B-Instruct微调指南:如何打造专属智能博物官(附数据集)

本文详细介绍了如何对Qwen3-Omni-30B-A3B-Instruct模型进行微调,以打造专业的智能博物官。指南涵盖了从理解模型架构优势、构建高质量文博数据集,到使用LLaMA-Factory进行实战微调、效果评估与部署优化的完整流程,并提供了关键的环境配置与性能优化建议,帮助开发者在垂直领域高效定制专属AI助手。

weixin_29096377的博客 1144

【c++语言特性—面试必考点】第四篇:非必要不提供default constructor

非必要不提供default constructor ​ default constructor的意思是在没有外来信息的情况下,为对象进行默认初始化,数值对象可以被初始化为0或者一个无意义值,指针可能被初始化为NULL,或者无意义值,像数据结构如Link lists,hash tables,maps等,被初始化为空容器。 ​ 但是对于某些类的对象你进行默认初始化,产生出来的对象将毫无意义,比如姓名册,设备识别编号之类的。这几乎总是造成class内的其他member function变得复杂,因.

Sefr后端 207

激光雷达与相机外参标定(附open3d python代码)

现在的激光雷达与相机的标定程序基本都是Ubuntu框架下面的,并且都是C++代码,需要安装的依赖也比较复杂,于是自己写了一个python版本的标定程序,依赖非常简单,Windows系统也可以运行。我这里用的大疆的雷达,点比较密集,更容易用我这种方法标定,旋转的16,32线的雷达也可以用这种方法标定,只是标定点会相对难选取一些。2 手动在点云上选取N个标定点(每个点都对应图像上的点,顺序也要一致)3 通过PNP方法计算出二者的旋转投影矩阵,也就是外参矩阵。1 手动在图像上面选取N个标定点。

三维点云技术探索 3412

RFSoC全面解析(八)—— ZCU111 RFSoC评估工具的上位机界面

下面的内容的参考文献为:XILINX公司文档UG1287。 XILINX公司提供了一个RFSoC的ADC/DAC性能的评估工具或者叫评估系统,这个文档就是讲如何使用这个评估工具的。 整个评估系统总的框图如上图所示,评估系统由上位机、ZCU111开发板、子卡以及网线、射频线缆组成。 ZCU111开发板内主要使用的RFSoC外设为时钟驱动和DDR4,RFSoC的PS部分和PL部分都使用了。 PS部分发挥的功能为通过网口与上位机通信,通过IIC总线控制时钟驱动芯片以及数据流控制等;PL部分发挥的功能为

4381

04. 非必要不提供default constructor

在一个完美的世界中,凡是可以"合理地从无到有生成对象"的classes,都应该内含default constructors。而"必须有某些外来信息才能生成对象"的classes,则不必拥有default constructors。 但是,不过class缺乏一个default constructor,使用这个class时会存在某些限制。 在产生数组的时候,没有办法为数组中的对象指定constr...

xupeng1644的博客 1557

torch.nn.rnn实现循环神经网络

------------------------------------nn.rnn模型实现。#------------------------------------模型实现。#-----------------------------------训练模型。#-----------------------------------训练模型。#--------------------------------读取数据。实现循环神经网络,并在至少一个数据集上进行实验,从训练时间、预测精度、...

matlab_python22的博客 2971

More Effective C++ 条款4 非必要不提供 default constructor

1. 有些类的数据成员的值是必要的,因而在创建时就应该提供其值,其中的一个强制实现的方法就是不提供默认构造函数,如果不这么做的话,在使用对象的时候就要检验那个数据成员是否被正确赋值。 2. 如果为了强制某些数据成员在创建对象时就被赋值而不提供默认构造函数,那么在创建该对象的数组时就会遭遇因为没有默认构造函数而无法创建的情况,主要的解决方法有以下三种: 1)在堆栈中创建数组并使...

ddzai7557的博客 173

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

MEC | 条款4 非必要不提供 default constructor

如果谨慎设计 template, 可以消除对default constructor 的需求,例如标准库中的 vector template 会产生出行为类似的“可扩展数组”的各种 classes,不要求其类型参数拥有一个 default constructor.当我们定义1个类,如果没有定义构造函数,C++会默认提供1个构造函数(Constructors),用来将对象初始化,因此,一般来说,“合理地从无到有生成对象”的 classes,都应该内含 default constructors,而。

RandyOliver's House 184

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

More Effective C++(条款四:非必要不提供 default constructor)

    默认构造函数可以初始化基本类型的成员变量,但是自定义的类型就不能正确初始化了。在这种情况下,需要我们自定义构造函数。但是,如果我们缺少默认的构造函数,会造成后续使用该类的时候会有一些限制。1. 有些类的数据成员的值是必要的,因而在创建时就应该提供其值,其中的一个强制实现的方法就是不提供默认构造函数。如果不这么做的话,在使用对象的时候就要检验那个数据成员是否被正确赋值。   2. 如果为了强...

Unique-You的博客 270

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

条款3-4:绝对不要以多态的方式处理数组与default constructor

条款3:绝对不要以多态的方式处理数组 class BST{ ...... }; class BalancedBST:public BST{.......}; void printBST(ostream& s,const BST array[ ],int num) {    for(int i = 0;i      s } 当你传入BST的数组是没有什么问题的。 现在传入B

652

More Effective C++ ——基础议题

条款1: 仔细区别Pointers和References 均用于间接指向其他对象,pointer存储对象所在的地址(4个字节),reference实质上是对象的别名: 1 显式区别:pointer定义时使用符号 ‘*’ ,reference定义时使用符号 ‘&’ (&用于指针表示取某个变量的地址,将其赋值给指针变量);Pointer访问指向的对象时...

July__的博客 294

More Effective C++之4

条款4:非必要不提供default constructor       对这一条款之中的详情,我处于半解之中。首先要说的是,关于default constructor在不显示提供的情况下,不同编译器存在不同的策略。我不认为所有编译器在这里会提供同样的方法。如果显示的提供这样的方法。我觉得未见得不好。我拿VC6作了一个测试,检测VC6的策略。测试表明default constructor会递归调

李永亮的专栏 830

华为应用市场审核 7.21 条款深度解析:UniApp 权限告知 3 种实现方案对比

本文深度解析华为应用市场7.21条款下UniApp权限告知的合规要求,对比原生监听、条件编译和社区插件三种技术方案。重点介绍原生Android权限体系的集成方法,提供动态权限说明管理和完整代码示例,帮助开发者高效通过华为应用市场审核,确保权限告知同步合规。

Hi, Sun 384

More Effective C++ 01 基础议题

More Effective C++ 基础议题

yuyuyuj1e的博客 507

编译器肯定会为没有constructor的类生成一个default constructor吗? ——感叹国内教科书中的常识性错误...

看完了《inside c++ object model》,接下来,就是亲自动手实践验证了。 依然记得大二时候那本清华大学出版社出版的C++教材,我用了2周时间就看完了,那时候的我还没有任何面向对象的思想,更别提项目经验了。感觉整个C++就是把C的struct扩充了一下,又加了点多态机制和泛型编程罢了(事实上,那时候对多态和泛型编程的概念也不是很清楚,只知道virt...

weixin_34221773的博客 176

More Effective C++ 随笔 1 to 4 基础议题

1.仔细区别pointers与reference (1)当一个指向有可能出现为NULL指向空时,那么应该使用pointers。 reference必须要指向一个对象而决不能为NULL,也因此,reference必须要有初始值。 同时也正因为reference不含NULL的情况,因此reference会比pointers更富效率(使用前不需要测试其有效性)。 (2)当需要可变的指向,也即可能会在不同...

lxx909546478的博客 211

Effective C++ 学习笔记

条款1.pointer和reference:当需要指向某个东西,而且绝不会改变指向其他东西或实现一个操作符而其语法需求无法由pointers达成,你就应该选择references,任何其他时候,请采用pointers 条款2.最好使用c++转型操作符:static_cast ,const_cast,dynamic_cast(继承体系向下安全转换),  reinterpret_cast(转换函数指

SwenV5的专栏 640

More Effective C++之基础主题basic

基础议题,包括pointers, references, casts, arrays,constructors,这一章描述pointer和reference的差异,并告诉你它们的适当使用时机。本章介绍新的C++转型(casts)语法,并解释为什么新式转型法比旧式的C转型法优越。本章也检验了C的数组概念即C++的多态(polymorphism)概念,并说明为什么将这两者混用是不明智之举。

chnming1987的博客 759

【more effective c++读书笔记】【第1章】基础议题(2)

条款3:绝对不要以多态方式处理数组 1、继承的最重要性质之一就是,你可以通过指向基类的指针或者引用来操作派生类对象。但是如果你通过基类指针或者引用来操作派生类所形成的数组,它几乎绝不会按你预期般地运作。 例子: #include using namespace std; class Base{ public: Base(int i=1){ ib = i; } friend ostrea

ruan875417的专栏 456
上一篇: 条款3:绝对不要以多态方式处理数组
下一篇: 数据结构--图
Nim的辙迹
博客等级 码龄10年 17粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值