当前位置: 首页 > news >正文

C++ 八股文: 构造函数

什么是构造函数

构造函数(Constructor)是一种特殊的成员函数,用于在创建对象时进行初始化。它的作用是确保对象在创建后处于一个合法和可用的状态。构造函数在类定义中声明,其名称与类名相同,但不带返回类型。

写一个拷贝构造函数?为什么你写的是引用传递?而不是值传递?(除了效率上的问题外)

拷贝构造函数用于创建一个对象的拷贝,通常在以下情况下使用:

  1. 通过值传递方式将对象传递给函数。
  2. 通过值返回方式从函数返回对象。
  3. 在创建一个对象作为另一个对象的拷贝时(如对象初始化或赋值)。

拷贝构造函数通常使用引用传递,而不是值传递,因为值传递会导致对象的无限递归复制,陷入无限循环。这是因为拷贝构造函数本身会创建一个新对象,如果将参数传递给拷贝构造函数时使用值传递,会导致无限递归的拷贝。

以下是一个示例拷贝构造函数,使用引用传递参数:

class MyObject {
public:int value;// 拷贝构造函数MyObject(const MyObject& other) {value = other.value;}
};int main() {MyObject obj1;obj1.value = 42;// 通过拷贝构造函数创建 obj2 作为 obj1 的拷贝MyObject obj2 = obj1;// obj1 和 obj2 现在有相同的值std::cout << obj1.value << " " << obj2.value << std::endl;return 0;
}

在上述示例中,拷贝构造函数 MyObject(const MyObject& other) 接受一个引用参数,这样可以避免无限递归的拷贝。如果我们将参数改为值传递,将导致无限循环的拷贝,直到栈溢出。

除了效率问题,使用引用传递还可以避免不必要的资源分配和释放。通过引用传递,只是传递了对象的引用而不是整个对象的拷贝,因此效率更高。此外,使用引用传递也更符合对象的语义,因为拷贝构造函数的目的是创建一个新对象,而不是复制对象的所有内容。所以,使用引用传递是一种更好的做法。

构造函数重载:

  • 作用

    • 初始化对象的成员变量。
    • 分配和管理资源,如内存分配、文件打开、数据库连接等。
    • 执行其他必要的初始化操作。
  • 语法

    class ClassName {
    public:// 默认构造函数(无参数)ClassName() {// 构造函数的实现}// 带参数的构造函数ClassName(Type1 param1, Type2 param2, ...) {// 构造函数的实现}
    };
    

    构造函数的语法示例中:

  • ClassName 是类的名称。
  • public 部分用于指定构造函数的访问权限,通常是公共的,以允许外部代码创建对象。
  • 构造函数的名称与类名相同。
  • 可以定义多个构造函数,每个构造函数具有不同的参数列表,允许不同的对象初始化方式。

为什么构造函数不能为虚函数?

构造函数不能为虚函数的原因是与对象的创建和初始化顺序以及虚函数机制有关。虚函数的特性和构造函数的执行顺序之间存在矛盾,因此构造函数不能被声明为虚函数。以下是相关的解释:

  1. 对象的初始化顺序:对象的初始化是按照继承层次从基类到派生类的顺序进行的。首先,基类的构造函数被调用,然后依次调用派生类的构造函数。这个初始化顺序是固定的。

  2. 虚函数的调用依赖于对象的类型:虚函数的调用是依赖于对象的类型的,而不是对象的构造过程。当对象被创建时,它在构造函数内部还没有完全初始化,因此对象的类型可能尚未被确定。虚函数调用要等到对象完全初始化后才有意义。

由于构造函数在对象的初始化阶段执行,而虚函数的调用依赖于对象的完全初始化,将构造函数声明为虚函数会导致潜在问题:

  • 构造函数声明为虚函数会导致不确定性,因为在构造函数内部,对象的类型可能还不确定,虚函数调用可能会指向错误的实现。
  • 基类构造函数的调用是在派生类构造函数之前发生的,因此派生类的虚函数表尚未完全设置,使得虚函数无法正确调用。
  • class Base {
    public:virtual void foo() {// 虚函数}Base() {foo(); // 构造函数中调用虚函数}
    };class Derived : public Base {
    public:void foo() override {// 派生类的虚函数实现}
    };
    

    在这个示例中,如果 Base 的构造函数声明为虚函数,那么在调用 foo() 时,派生类的虚函数实现还没有生效,因此无法调用正确的虚函数。这是为什么构造函数不能为虚函数的一个示例。

    总之,构造函数不能声明为虚函数,因为虚函数的调用依赖于对象的完全初始化,而构造函数的目标是初始化对象。为了避免潜在的问题和不确定性,最好将构造函数保持为普通的成员函数,而将虚函数用于对象完全初始化后的多态操作。

构造函数使用private

将构造函数声明为private是一种封装技巧,它通常用于实现单例模式、工厂模式或其他只允许有限途径创建对象的情况。当构造函数被声明为private时,只有类内部的函数可以访问它,外部代码无法直接创建类的实例。

下面是一个示例,展示了如何将构造函数声明为private

class Singleton {
public:// 获取唯一的实例static Singleton& getInstance() {static Singleton instance; // 在首次调用时创建唯一的实例return instance;}// 其他成员函数void doSomething() {// 执行操作}private:// 构造函数私有,防止外部代码直接创建对象Singleton() {// 构造函数的实现}// 防止复制和赋值操作Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};

在上述示例中,构造函数Singleton()被声明为private,防止外部代码直接创建Singleton类的实例。相反,通过公共的静态成员函数getInstance()来获取唯一的实例。这确保了只有一个Singleton对象存在。

通过将构造函数声明为private,你可以实现更严格的对象创建控制,确保对象的唯一性,同时提供一个公共的方法来获取实例。这在单例模式等情况下非常有用。

构造函数的初始化列表和构造函数体内的赋值操作之间有一些重要的区别:

  1. 执行时间:

    • 初始化列表:构造函数初始化列表在进入构造函数体之前执行。这意味着它们在对象的成员变量构造之前执行,可以在构造函数体内访问这些成员变量。
    • 构造函数体内的赋值:赋值操作在构造函数体内执行,因此它们在对象的成员变量已经构造之后执行。这意味着它们不能在构造函数体内初始化成员变量。
  2. 效率:

    • 初始化列表:使用初始化列表通常更高效,因为它直接初始化成员变量,而不是先默认初始化然后再赋值。
    • 构造函数体内的赋值:在构造函数体内赋值需要两步操作:首先默认初始化成员变量,然后再进行赋值操作,可能会引入额外的开销。
  3. 成员变量的类型:

    • 初始化列表:适用于非静态成员变量和const成员变量,以及基本类型(如int、double)。
    • 构造函数体内的赋值:在构造函数体内可以用于更多的情况,包括对非const成员变量、静态成员变量和复杂类型(如类对象)的初始化。
  4. 顺序:

    • 初始化列表:允许你指定成员变量的初始化顺序,即使它们在类中的声明顺序不同。这有助于避免潜在的问题,如依赖于初始化顺序的成员变量之间的问题。
    • 构造函数体内的赋值:通常依赖于成员变量的声明顺序,因此如果声明顺序与所需初始化顺序不同,可能需要小心。

综上所述,初始化列表通常是更好的选择,特别是对于非静态和const成员变量。它提供了更高效的初始化方法,更好的控制初始化顺序,以及更清晰的代码结构。但对于其他情况,如在构造函数体内需要进行复杂的计算或条件判断来确定成员变量的值,构造函数体内的赋值操作可能更合适。

相关文章:

C++ 八股文: 构造函数

什么是构造函数 构造函数&#xff08;Constructor&#xff09;是一种特殊的成员函数&#xff0c;用于在创建对象时进行初始化。它的作用是确保对象在创建后处于一个合法和可用的状态。构造函数在类定义中声明&#xff0c;其名称与类名相同&#xff0c;但不带返回类型。 写一个…...

自动切割短视频的软件推荐,一键生成1000条短视频,支持六大主流平台矩阵分发,快来免费试用

经过小编的多方测评&#xff0c;今天给大家推荐一款性价比、好评率、专业性全都超高的软件——超级编导批量剪辑软件&#xff0c;更重要的是这款软件支持免费试用&#xff0c;一起来看看超级编导如何帮助大家自动分割视频的吧。 复制视频链接&#xff0c;一键上传视频素材后&am…...

从零开始学习秒杀项目

构思了很多种讲述这个简易版的秒杀项目的思路&#xff0c;比如按照功能分类&#xff0c;按照项目亮点串起来讲述&#xff0c;总觉得不适合基础薄弱的同学来学习&#xff0c;所以本项目按照从搭建开始&#xff0c;过程中需要什么来学习什么。 技术栈 SpringBootmybatisPlus&am…...

儿童珠宝首饰上亚马逊美国站合规标准是什么?如何办理?

儿童珠宝首饰 儿童珠宝首饰指原则上由 12 岁及以下儿童作为装饰品移除或穿戴的商品。本政策涵盖的儿童珠宝首饰&#xff0c;包括但不限于脚链、手链、耳环、项链、戒指、珠宝首饰制作或维修套装以及钟表。 亚马逊儿童珠宝首饰政策 亚马逊要求所有儿童珠宝首饰均经过检测并符合…...

ORACLE 19C PDB FOR MYSQL 5.7 部署ogg

一、--软件配置 角色 数据库/软件版本 OGG版本 IP ---------- ----------------- ------------------------------- ----------- 源端服务器 Oracle Datbase 19 Oracle C##GOLDENGATE 19.1.0.0.4 10.10.10.32 目标服务器 MYSQ…...

前端 html 中的 meta 标签有哪些用处?

HTML中的<meta>标签用于提供有关文档的元数据&#xff08;metadata&#xff09;&#xff0c;它们不会在页面上显示出来&#xff0c;而是提供有关页面的信息&#xff0c;使搜索引擎和浏览器能够更好地理解和使用文档。下面是一些常见的用途&#xff1a; 1、指定文档的字符…...

罗技鼠标接收器丢失或损坏后用另一个接收器配对的方法

本文介绍罗技鼠标在丢失、损坏其自身原有的接收器后&#xff0c;将另一个新的接收器与原有鼠标相互配对的方法。 在开始之前&#xff0c;大家需要首先查看两个内容&#xff1a;首先是原有的鼠标——大家需要查看自己的鼠标&#xff08;罗技键盘也是同样的操作&#xff09;底部&…...

Python语法

文章目录 一、Python基础1. 数据类型和变量2. 字符串和编码字符编码Python的字符串格式化 3. list和tuplelisttuple 4.条件判断5. 模式匹配6. 循环7. dict 和 setdictset 二、函数1. 调用函数2. 定义函数3. 函数的参数4. 递归函数 三、高级特性四、函数式编程1. 高阶函数2. 返回…...

电脑经营商城小程序的作用是什么

电脑是企业办公必备的工具&#xff0c;同时很多家庭都有配备&#xff0c;无论笔记本还是台式在各场景中应用都非常广泛&#xff0c;市场各类品牌也很多&#xff0c;区别于以前店内购买&#xff0c;现在不少消费者会选择线上电商平台购买&#xff0c;也因此如今电脑经销商或品牌…...

森海塞尔EW-DP SKP直插式发射机:真正的无失真录制

韦德马克&#xff0c;2023年9月15日 – 10月底&#xff0c;EW-DP系列将再添新品——EW-DP SKP直插式发射机&#xff0c;面向摄像师、广播电视公司和电影制作人。板载32位浮点录制&#xff0c;结合该系列领先的134 dB发射机动态范围&#xff0c;让音频失真不复存在。无论要在现场…...

通过小程序实现会议Oa的会议展示以及个人中心

&#x1f3c5;我是默&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《微信小程序 》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;…...

STM32驱动GY-39监测环境温度,湿度,大气压强,光强度

目录 模块简介模块测试接线代码测试现象 总结 模块简介 GY-39 是一款低成本&#xff0c;气压&#xff0c;温湿度&#xff0c;光强度传感器模块。工作电压 3-5v&#xff0c;功耗小&#xff0c;安装方便。 其工作原理是&#xff0c;MCU 收集各种传感器数据&#xff0c;统一处理&…...

在华为和比亚迪干了5年测试,月薪25K,熬夜总结出来的划水经验.....

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入华为&#xff0c;之后跳槽到了比亚迪&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是5年的工作经验吧。 这5年之间完成了一次晋升&#xff0c;换了一家公司&#xff0c;…...

Mac 使用 scp 上传或下载文件/文件夹

目录 上传文件到远程服务器 scp 本地文件路径 远程用户名远程IP&#xff1a;远程目标目录上传文件夹到远程服务器 scp -r 本地文件夹 远程用户名远程IP&#xff1a;远程目标目录从远程服务器下载文件 scp 远程用户名远程IP&#xff1a;远程文件路径 本地目标目录从远程服务器下…...

Restful 风格

目录 Restful风格创建springboot项目SpringMVC开发Restful接口1、获取所有的员工思路代码RequestMappingGetMapping 2、获取单个员工思路代码注意&#xff1a; 3、删除员工数据思路&#xff1a;代码单个删除批量删除 4、更新员工数据思路&#xff1a; 5、jQuery发送请求发送del…...

LLM 系列 | 21 : Code Llama实战(上篇) : 模型简介与评测

引言 小伙伴们好&#xff0c;我是《小窗幽记机器学习》的小编&#xff1a;卖热干面的小女孩。 个人CSDN首页&#xff1a;JasonLiu1919_面向对象的程序设计,深度学习,C-CSDN博客 今天开始以2篇小作文介绍代码大语言模型Code Llama。上篇主要介绍Code Llama的基本情况并基于Hug…...

积分球荧光光谱测试光电检测方式有哪些优点?

积分球荧光光谱测试是一种测量光通量的方法&#xff0c;其基本原理是将待测光源放入积分球中&#xff0c;在积分球内壁涂以白色漫反射层&#xff0c;光源发出的光经球壁多次反射后&#xff0c;使整个球壁上的照度均匀分布&#xff0c;再通过球壁上的孔投射到光电探测器上的光通…...

软考考试时间已出!采用连考形式!

2023年下半年计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试批次安排已出&#xff01;下面是具体的考试安排。 通知原文如下&#xff1a;↓↓↓ 按照《2023年下半年计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试有关工作调整的通告》&#x…...

深入理解强化学习——学习(Learning)、规划(Planning)、探索(Exploration)和利用(Exploitation)

分类目录&#xff1a;《深入理解强化学习》总目录 学习 学习&#xff08;Learning&#xff09;和规划&#xff08;Planning&#xff09;是序列决策的两个基本问题。 如下图所示&#xff0c;在强化学习中&#xff0c;环境初始时是未知的&#xff0c;智能体不知道环境如何工作&a…...

大模型LLM相关面试题整理-训练集-训练经验-微调

3 大模型&#xff08;LLMs&#xff09;微调 3.1 如果想要在某个模型基础上做全参数微调&#xff0c;究竟需要多少显存&#xff1f; 要确定全参数微调所需的显存量&#xff0c;需要考虑以下几个因素&#xff1a; 模型的大小&#xff1a;模型的大小是指模型参数的数量。通常&…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...