C++细节之四----再论四大函数

C++通用工具库cpp-utilities:告别重复造轮子,提升开发效率 在C++开发中,字符串处理、文件操作、时间日期等基础功能是每个项目都绕不开的通用需求。这些看似简单的功能,若每次都从零实现或从网络拼凑,不仅效率低下,还会引入风格不一、质量参差不齐的代码,为项目埋下隐患。cpp-utilities正是为解决这一痛点而生的轻量级头文件库,它遵循现代C++标准,提供了一套经过充分测试、高效可靠的通用工具集。其核心价值在于通过模块化设计,将开发者从重复劳动中解放出来,让开发者能更专注于核心业务逻辑。无论是快速原型验证,还是需要长期维护的生产项目,cpp-utilities都能作为 阅读详情

     在建立一个类的过程中,首先应该考虑的是,有哪些成员变量,即对象拥有的属性,第二步抽象出类的接口,即需要哪些成员函数,并确定访问权限。第三步,当然是考虑如何为类建立构造函数和析构函数了。对于成员变量中有指针的情况,需要提供拷贝构造函数和赋值函数。

 

     1 构造函数:这个函数里面有许多需要注意的问题,第一,成员变量的赋值是放入初始化成员列表中,还是放在构造函数内部,两者的区别是什么?第二,哪些成员变量必须放在初始化成员列表中?第三,初始化顺序是根据什么规则来的?

 

    首先解答第一个问题,借用《Effective C++》条款12来说,尽量使用初始化列表,这样做主要是从效率来考虑的,避免多次函数调用总是高效的。如果一个类中有一个成员变量是某个类的变量,那么当这个类实例化之前,成员变量的对象初始化已经结束,这肯定是调用了一次缺省构造函数,如果在类的构造函数次赋值,那么就调用了2次函数,一次是缺省构造函数,一次可能是赋值函数,这样明显效率就不高。如果使用成员列表,那只需要调用一次。为了更好的说明这个问题,举一个例子。

template<class t>
class namedptr {
public:
  namedptr(const string& initname, t *initptr);
  ...

private:
  const string name;
  t * const ptr;
};

     对namedptr类来说,这意味着string对象name的构造函数总是在程序执行到namedptr的构造函数体之前就已经被调用了。问题只在于:string的哪个构造函数会被调用?

    这取决于namedptr类的成员初始化列表。如果没有为name指定初始化参数,string的缺省构造函数会被调用。当在namedptr的构造函数里对name执行赋值时,会对name调用operator=函数。这样总共有两次对string的成员函数的调用:一次是缺省构造函数,另一次是赋值。

    相反,如果用一个成员初始化列表来指定name必须用initname来初始化,name就会通过拷贝构造函数以仅一个函数调用的代价被初始化。

 

    解答第二个问题,哪些成员变量必须放在初始化成员列表中?对于const成员变量必须放在初始化列表中来赋值,因为const变量只能初始化不能赋值。对于引用成员变量必须放在成员初始化列表中,因为一个引用变量,引用的同时必须初始化。

 

    解答第三个问题,第三,初始化顺序是根据什么规则来的?程序总是先执行初始化列表,再执行构造函数体。然而,初始化列表的顺序又是如何呢?初始化顺序跟类中成员变量的声明顺序是一样的,而和初始化列表中的顺序无关。这是编译器设置的,如果不这样做会产生很多问题。

 

    2 拷贝构造函数:objectA(objectB),这样的对象初始化调用的是拷贝构造函数,如何编写该函数?以下是一个很简单的string类。

// 一个很简单的string类
class string {
public:
  string(const char *value);
  ~string();

private:
  char *data;
};

string::string(const char *value)
{
  if (value) {
    data = new char[strlen(value) + 1];
    strcpy(data, value);
  }
  else {
    data = new char[1];
    *data = '/0';
  }
}

    从上面的函数来说,拷贝构造函数总是要动态分配一个内存,然后根据参数为成员变量赋值。

 

    3 赋值函数:主要是为对象初始化支持=操作符。

 

     A 当定义自己的赋值运算符时,必须返回赋值运算符左边参数的引用,*this。如果不这样做,就会导致不能连续赋值,或导致调用时的隐式类型转换不能进行,或两种情况同时发生。因此,该函数必须返回*this.

 

     B 在operator=函数中为所有的数据成员赋值,包括从基类里继承下来的数据成员,因此必须在子类的operator=中调用基类的operator=函数。如下代码:

 

// 正确的赋值运算符
derived& derived::operator=(const derived& rhs)
{
  if (this == &rhs) return *this;

  base::operator=(rhs);    // 调用this->base::operator=
  y = rhs.y;

  return *this;
}

 

    C 在operator=中检查给自己赋值的情况,即每一个operator=函数中加入一行代码if (this == &rhs) return *this,这样做的原因如下:

 

做类似下面的事时,就会发生自己给自己赋值的情况:

class x { ... };

x a;

a = a;                     // a赋值给自己

这种事做起来好象很无聊,但它完全是合法的,所以看到程序员这样做不要感到丝

毫的怀疑。更重要的是,给自己赋值的情况还可以以下面这种看起来更隐蔽的形式

出现:

a = b;

如果b是a的另一个名字(例如,已被初始化为a的引用),那这也是对自己赋值,

虽然表面上看起来不象。这是别名的一个例子:同一个对象有两个以上的名字。

 

  4 析构函数:用着基类的析构函数必须为虚函数,析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数。如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数。这样会造成销毁对象不完全。

2025年C++通信库性能横评:NNG、brpc、tRPC-Cpp与gRPC实战对比 在现代分布式系统与微服务架构中,高性能网络通信是核心基石,其关键在于如何高效处理高并发请求与低延迟数据传输。其原理通常涉及I/O多路复用、协程调度、连接复用及零拷贝等技术,以最大化利用CPU与网络资源。这些技术的价值在于支撑起海量用户访问、实时数据处理等关键业务场景。本次评测聚焦于C++生态中主流的通信库,通过模拟微服务RPC、实时数据流推送及高并发短连接等典型应用场景,结合**性能测试**与**调优参数**的深度实践,对比分析了NNG、brpc、tRPC-Cpp和gRPC在极限吞吐、尾部延迟及资源效率等方 阅读详情

相关推荐

函数设计四大核心特性:从内置函数到模板重载的工程实践

在编程中,函数是构建软件的基础单元,其设计质量直接影响代码的可读性、可维护性和性能。理解函数的核心特性,如内置函数和函数重载,是提升代码质量的关键。内置函数由语言标准库提供,经过充分优化和测试,能有效避免重复造轮子,确保功能的可靠性和跨平台一致性。函数重载则允许在同一作用域内定义多个同名函数,通过参数列表的差异实现多态,显著提升代码的表达力和可读性。这些特性共同支撑起现代软件工程中模块化、泛型编程等核心思想,广泛应用于算法库、工具类设计、API接口封装等场景。本文以C++为例,深入解析内置函数、函数重载、函

weixin_30596735的博客 360

C++四大函数

C++四大函数

yjx的博客 579

C++进阶三:类和对象的细节原理

面向对象四大特性::抽象是一种将对象的共同特征提取出来并定义成一个通用模板的过程。类的抽象是指将一个类的共同属性和行为抽象出来,定义一个通用的类模板,而不关注具体的实现细节。:数据和代码捆绑在一起,避免外界干扰和不确定性访问。封装可以使得代码模块化。优点:确保用户代码不会无意间破坏封装对象的状态;被封装的类的具体实现细节可以随时改变,而无须调整用户级别的代码。:让某种类型对象获得另一个类型对象的属性和方法,继承可以扩展已存在的代码。

m0_71124168的博客 643

【C++面向对象编程】四大基本特性之四:抽象

在C++面向对象编程中,抽象(Abstraction)是四大基本特性(封装、继承、多态、抽象)之一,它允许我们关注对象的高层逻辑,而隐藏复杂的实现细节。抽象通过定义抽象类和接口来实现,这些类和接口只暴露必要的操作,而将具体的实现细节隐藏起来。

byte轻骑兵的技术小窝 2547

50、探索C++20:四大支柱与未来发展

本文深入探讨了C++20的四大支柱——概念、模块、范围和协程,分析了它们如何改变现代C++编程方式,并展望了C++23可能带来的新特性,如协程库、模块化标准库、执行器、网络功能、反射、模式匹配和合约。通过实际应用案例展示了如何在项目中有效利用这些特性,提升开发效率和代码质量。

rgv23456789的博客 386

34、探索C++20的深度:四大核心特性详解

本文深入探讨了C++20的四大核心特性:概念(Concepts)、模块(Modules)、范围库(Ranges Library)和协程(Coroutines),并介绍了其在并发编程、内存管理和字符串操作等方面的改进。通过实际代码示例,展示了如何利用这些新特性编写高效、可靠的代码,并提供了最佳实践建议。

rgv23456789的博客 402

【C++】类与对象中篇:四大默认成员函数深度解析

本文全面深入地探讨C++中四大默认成员函数:构造函数、析构函数、拷贝构造函数和赋值运算符重载。通过详细分析每个函数的语法特性、设计原理及实际应用,结合具体代码示例,揭示面向对象编程中对象生命周期管理、资源初始化和拷贝机制的核心概念,为编写健壮、高效的C++代码奠定坚实基础。

2403_88316985的博客 912

Dev-Cpp 6.3开源集成开发环境源码深度解析

别看它界面复古(甚至有点 Win98 风格),但 Dev-Cpp 实际上是四大技术栈的经典融合体。它不像 Qt Creator 或 Visual Studio 那样依赖庞大框架,而是以极简方式串联起整个开发链条。这种“原生集成”的做法,反而让它成为学习桌面级开发工具的理想样本:它不抽象、不封装过度;所有系统调用都清晰可见;没有 Electron 壳子拖慢性能;更没有 JavaScript 中间层做桥梁。

weixin_36300623的博客 596

谈一谈C++语言面向对象的四大特性----【封装 继承 多态 抽象】

C/C++工程编译时候都干了什么?开发流程说明编译流程说明1. 编译流程概述:2. 编译流程中的阶段1. 预处理过程2. 编译过程3. 汇编过程4. 链接过程功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 开发流程说明 C/C++

qq_15730877的博客 1025

T2T基因组组装实战指南:从数据到完整染色体

本文详细介绍了T2T基因组组装技术的实战指南,从测序数据选择到完整染色体组装的全流程。重点解析了ONT ultra-long和PacBio HiFi测序技术的优势,以及如何攻克端粒和着丝粒等重复区域的组装难题。通过具体案例和实用技巧,帮助研究人员实现从数据到完整染色体的高质量组装。

weixin_29292535的博客 845

Unity与IOS交互,调用IOS系统相机和相册

与IOS的交互,在步骤上要比android简单许多,不会产生因为系统版本,或者包名导致的许多问题。过程中最头疼的一个问题是IOS回调Unity,很简单的一个问题,搞了半天。

Hello Mingo 1万+

AndroidRuntime.cpp:打通C++与Java的桥梁

摘要: AndroidRuntime.cpp是Android系统连接C++与Java层的核心桥梁,主要承担四大职责: 启动JVM,加载Java世界入口(如SystemServer); 注册JNI方法,建立双向调用映射; 管理线程通信,为Native线程分配JNIEnv*; 异常处理与日志。 源码中关键方法包括startVm()、startReg()等,它既是JVM的启动器,又是跨语言调用的翻译中枢,贯穿Android系统启动与运行的全流程。(149字)

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 235

从扇束到平行束:等角重排算法在CT重建中的核心原理与MATLAB实践

本文深入解析了CT图像重建中等角扇束重排算法的核心原理与MATLAB实现。通过将实际采集的扇束投影数据,利用几何映射和两次关键插值,转换为适用于经典滤波反投影算法的平行束数据,打通了高效重建的关键路径。文章结合Shepp-Logan模型仿真,提供了完整的MATLAB代码实践,并分析了源-物距、采样率等关键参数对重建质量的影响。

cnn8visionary的博客 646

【初级C++工程师】3.C++面向对象——类和对象的那些你不知道的细节原理

本系列文章仅作为施磊老师C++课程的自学笔记,如有错误请多指正!

weixin_51722352的博客 2075

Hypermesh二次开发实战:Tcl命令分类与常用函数详解(附避坑指南)

本文深入解析Hypermesh二次开发中Tcl命令的三大核心类别:界面命令、查询命令与修改命令。重点剖析了*createmark集合管理与hm_getvalue信息查询等关键函数的实战用法,并提供了避免Mark覆盖、生命周期管理等常见陷阱的实用指南,旨在帮助CAE工程师构建高效可靠的自动化前处理流程。

weixin_29233333的博客 239

【YOLOv11工业级实战】15. YOLOv11海洋监测实战:珊瑚礁健康评估(水下图像增强|机器人搭载)

摘要:本文针对珊瑚礁健康评估的海洋监测需求,基于YOLOv11提出解决方案,聚焦水下色偏、悬浮物干扰、珊瑚形态复杂三大难题。引用全球珊瑚礁监测网络(GCRMN)标准,采用CoralNet数据集,通过Jaffe-McGlamery物理模型引导增强与悬浮物去除算法,在浑浊水域(能见度<5m)实现87.3%的健康珊瑚识别率,藻类误判率低至7.2%。介绍了以BlueROV2水下机器人和Jetson AGX Orin为核心的部署方案,结合水下SLAM定位技术,实现珊瑚健康的实时评估与三维覆盖率计算。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1644

从 C 到 C++:用 C 语言思维理解面向对象四大特性

将数据和操作数据的方法捆绑在一起,隐藏内部细节,只暴露必要的接口。就像一台电视机,我们不需要知道内部电路如何工作,只需通过按钮(接口)来操作。继承允许我们创建新类(子类)来复用已有类(父类)的代码,子类可以继承父类的属性和方法,并添加自己的特性。就像 "学生" 和 "老师" 都继承了 "人" 的属性(姓名、年龄),但又有各自的特殊属性(学生有分数,老师有工资)。同一操作作用于不同对象,会产生不同的结果。比如 "动物叫" 这个操作,狗会 "汪汪叫",猫会 "喵喵叫"。

SundayBear的博客 933

开源免费!ReaLTaiizor如何用MIT许可证打造专业级WinForm UI?

摘要: ReaLTaiizor是一款开源UI控件库,为WinForm应用提供现代化界面解决方案。支持100+组件、多主题切换(浅色/深色/自定义)和.NET 4.8-8.0全版本兼容,MIT许可证允许免费商用。通过NuGet快速安装,3步改造传统界面:1)注入主题(如this.Theme = new Dark()),2)替换原生控件为高颜值组件(如ModernGrid替代DataGridView),3)集成高级功能(分页/动画提示)。典型场景包括登录界面美化(进度动画+通知控件)和数据表格Material风

墨夶的博客 1520

C++类与对象基础:类、对象定义 类成员默认四大函数

本文摘要:C++类定义使用class/struct关键字,class默认私有访问,struct默认公有。类成员需通过函数初始化,静态成员需类外定义。介绍了对象内存对齐规则和this指针的隐式作用。重点解析了类的四大默认函数:构造函数(初始化对象)、析构函数(清理资源)、拷贝构造函数(对象复制)和运算符重载函数(自定义操作符行为)。其中构造函数可重载,析构函数无参数,拷贝构造需引用传参避免递归,运算符重载需遵循特定规则。还对比了拷贝构造与赋值重载的区别,强调赋值运算符需返回引用以支持连续赋值。这些特性共同构成

深入探究的博客 961

Matlab之App Designer 如何进行三维图形绘制教程

基于Matlab中的App Designer设计可视化界面并进行数据导入及3D绘图,可以直观的在可视化界面上展示分析结果,方便用户进行图形的操作。本文采用案例讲解的方式,详细介绍了如何采用Matlab App Designer建立数据3D绘图的GUI可视化界面的方法和详细的过程步骤,并介绍了导入数据进行计算时需要注意的相关事项,同时提供了详细的代码,以便读者进行学习和操作。

m0_59012156的博客 2066

ABB机器人将实时坐标发送给西门子PLC的具体方法示例

ABB机器人将实时坐标发送给西门子PLC的具体方法示例

Robot_PLC_HMI_Automation 4914

【C++ 入门】:从语言发展脉络到实战细节 —— 详解命名空间、输入输出、缺省参数与函数重载

文章摘要 本文系统介绍了C++的核心特性,包括其发展历程、命名空间机制、输入输出操作、缺省参数及函数重载功能。C++在C语言基础上扩展了面向对象编程能力,通过命名空间解决全局命名冲突问题,提供更简洁的I/O流操作(如cout/cin)。缺省参数增强了函数调用的灵活性,而函数重载则允许同名函数根据参数差异实现不同功能。文章还对比了C++与C语言在函数重载支持上的底层差异(如名字修饰规则),帮助开发者理解C++的底层实现逻辑。适合作为C++基础特性的学习指南。(149字)

2402_86350387的博客 1625

android 蓝牙通讯demo

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

C++_chapter3_C++类和对象的细节原理

面向对象就是对现实的实体的属性和行为进行抽象,得到抽象数据类型ADT,比如实体的属性包括:年龄,姓名等;行为:吃饭,睡觉等。然后再通过计算机实现,就得到了类,对类进行实例化,就得到了对象。

weixin_43916755的博客 926

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

C++——4个默认成员函数详解

C++知识总结目录索引 本博客参照林锐《高质量程序设计指南C++/C语言》(第三版)第十三章完成   在C++中,每个类都有三种成员函数——构造函数、析构函数和赋值函数(ps:构造函数有构造函数和拷贝构造函数两种)。对于任意一个类A,如果不显式地声明定义以上函数,编译器会自动为A生成4个默认函数,如下: A(); //默认构造函数 A(co...

Tianzez的博客 1643

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

详解C++的四大特性(封装,继承,多态,抽象)

C++的四大特性是面向对象编程(OOP)的核心概念,分别是封装、继承、多态和抽象。这些特性共同构成了C++作为面向对象编程语言的基础。

不会编程的码农研究僧 1450

【②C++ | 类和对象】四大特性 | 创建 | 实例化

通过使用类和对象,可以将代码组织为更加模块化、可重用和易于维护的方式。类定义了对象的属性和行为,而对象则是这些属性和行为的实际体现。封装、继承和多态等概念使得面向对象编程成为一种强大的编程范式,可用于构建复杂的软件系统。

热爱编程的小K的博客 1823
上一篇: 从printf()看可变参数函数
下一篇: C语言获取文件后缀名
burningcpu
博客等级 码龄20年 13粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值