深入理解构造函数:C++ 编程中的基石

一、概念

        构造函数(Constructor) 是一种特殊的成员函数,用于在创建对象时初始化对象的状态(即成员变量)。它的主要作用是保证对象在创建时具有有效的初始值。


二、特点

与类同名

  • 构造函数的名称与类名相同,没有返回值(甚至不能写 void)。

自动调用

  • 构造函数在对象创建时自动调用,无需显式调用。

可以重载

  • 构造函数可以有多个版本,依赖于参数个数和类型(重载)。

无返回值

  • 构造函数没有返回值,也不能通过返回值来传递信息。

默认构造函数

  • 如果用户没有定义构造函数,编译器会自动生成一个无参的默认构造函数。
  • 如果用户定义了任何构造函数,编译器将不再生成默认构造函数。

三、种类

1. 默认构造函数

无参数的构造函数,称为默认构造函数。

  • 作用:初始化对象为默认状态。
  • 示例:
class Example {
public:Example() {  // 默认构造函数cout << "Default constructor called" << endl;}
};int main() {Example obj;  // 自动调用默认构造函数return 0;
}

2. 带参数的构造函数

构造函数可以带参数,用于初始化对象时传递参数。

  • 示例:
class Example {
private:int value;
public:Example(int v) {  // 带参数的构造函数value = v;cout << "Constructor called with value: " << value << endl;}
};int main() {Example obj(10);  // 调用带参数的构造函数return 0;
}

3. 拷贝构造函数

拷贝构造函数用于创建一个对象时,以另一个同类型的对象对其初始化。

  • 特点:参数是同类的引用类型,通常形式为 ClassName(const ClassName &obj)
  • 示例:
class Example {
private:int value;
public:Example(int v) {value = v;cout << "Parameterized constructor called" << endl;}Example(const Example &obj) {  // 拷贝构造函数value = obj.value;cout << "Copy constructor called" << endl;}
};int main() {Example obj1(10);         // 调用带参数的构造函数Example obj2 = obj1;      // 调用拷贝构造函数return 0;
}

4. 委托构造函数

一个构造函数可以调用另一个构造函数来简化代码逻辑。

  • 示例:
class Example {
private:int value;
public:Example() : Example(0) {  // 调用另一个构造函数cout << "Default constructor called" << endl;}Example(int v) {value = v;cout << "Parameterized constructor called with value: " << value << endl;}
};int main() {Example obj;   // 调用默认构造函数,同时委托到带参数的构造函数return 0;
}

5. 默认和删除的构造函数

  • 可以显式指定构造函数为默认的或删除的(C++11 引入)。
  • 示例:
class Example {
public:Example() = default;  // 默认构造函数Example(int) = delete;  // 禁止使用此构造函数
};int main() {Example obj1;     // 可以// Example obj2(10);  // 错误,无法使用删除的构造函数return 0;
}

四、构造函数的使用与初始化列表

初始化成员变量

可以在构造函数中直接初始化成员变量,或使用 初始化列表 初始化。

  • 示例:
class Example {
private:int a;int b;
public:Example(int x, int y) : a(x), b(y) {  // 初始化列表cout << "a = " << a << ", b = " << b << endl;}
};int main() {Example obj(10, 20);  // 调用构造函数return 0;
}

初始化列表

  • 初始化列表在对象构造时直接赋值,而不是先默认构造后再赋值,因此效率更高。
  • 某些情况必须使用初始化列表,例如常量成员变量或引用类型。

五、子类构造函数

工作流程

  1. 创建子类对象时,必须先调用父类的构造函数。
  2. 如果子类的构造函数没有显式调用父类的构造函数,则会默认调用父类的无参构造函数。
  3. 如果父类没有无参构造函数,子类必须显式调用父类的某个构造函数。

示例:

#include <iostream>
using namespace std;class Parent {
public:Parent(int x) {cout << "Parent constructor called with value: " << x << endl;}
};class Child : public Parent {
public:Child(int x) : Parent(x) {  // 显式调用父类的构造函数cout << "Child constructor called" << endl;}
};int main() {Child obj(10);  // 调用子类构造函数return 0;
}

输出:

Parent constructor called with value: 10
Child constructor called

六、构造函数的注意点

没有返回值: 构造函数没有返回值,不能使用 return 返回值。

拷贝构造函数的深拷贝与浅拷贝: 如果类中有指针类型成员变量,拷贝构造函数默认执行浅拷贝,这可能会导致资源冲突,建议实现深拷贝。

静态成员的初始化: 静态成员变量需要在类外初始化,不能通过构造函数初始化。

继承中的构造函数:父类的构造函数不会被子类继承,但可以通过子类构造函数显式调用。


构造函数与析构函数的关系

  • 析构函数与构造函数相反,用于对象销毁时释放资源。
  • 析构函数在子类对象销毁时按照从子类到父类的顺序调用。

示例:

#include <iostream>
using namespace std;class Parent {
public:Parent() { cout << "Parent constructor called" << endl; }~Parent() { cout << "Parent destructor called" << endl; }
};class Child : public Parent {
public:Child() { cout << "Child constructor called" << endl; }~Child() { cout << "Child destructor called" << endl; }
};int main() {Child obj;  // 创建子类对象return 0;
}

输出:

Parent constructor called
Child constructor called
Child destructor called
Parent destructor called

七、总结

  1. 构造函数是初始化对象的入口,可以重载。
  2. 带参数构造函数和拷贝构造函数提供了灵活的初始化方式。
  3. 初始化列表是高效的初始化方式,尤其适合常量或引用类型。
  4. 父类的构造函数必须在子类构造函数中显式调用(如果没有无参构造函数)。
  5. 析构函数与构造函数互补,用于释放资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63828.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GIS数据处理/程序/指导,街景百度热力图POI路网建筑物AOI等

简介其他数据处理/程序/指导&#xff01;&#xff01;&#xff01;&#xff08;1&#xff09;街景数据获取&#xff08;2&#xff09;街景语义分割后像素提取&#xff0c;指标计算代码&#xff08;绿视率&#xff0c;天空开阔度、视觉熵/景观多样性等&#xff09;&#xff08;3…

微前端qiankun的使用——实践

qiankun 创建主应用项目——vue2 main.js注册子应用 $ yarn add qiankun # 或者 npm i qiankun -Simport { registerMicroApps, start } from qiankun; import Vue from "vue"; import App from "./App.vue"; import router from "./router"; …

SAP SD客户主数据及其配置

一、客户主数据概述 在SD模块概览中对于SD模块及其有关的三大主数据进行了概要介绍&#xff0c;本篇文章将重点对于客户主数据进行有关介绍。 1、业务伙伴主数据 在提到客户主数据之前&#xff0c;我们先了解业务伙伴主数据的概念。 业务伙伴主数据是一个更广泛的概念&#x…

GitCode 光引计划征文展示|MilvusPlus:开启向量数据库新篇章

在人工智能和大数据时代&#xff0c;向量数据库作为处理非结构化数据的核心技术&#xff0c;正变得越来越重要。MilvusPlus&#xff0c;作为「光引计划」的一部分&#xff0c;应运而生&#xff0c;旨在提供一个高性能、易扩展、全功能的向量数据库解决方案。项目背景根植于对现…

网络架构与IP技术:4K/IP演播室制作的关键支撑

随着科技的不断发展&#xff0c;广播电视行业也在不断迭代更新&#xff0c;其中4K/IP演播室技术的应用成了一个引人注目的焦点。4K超高清技术和IP网络技术的结合&#xff0c;不仅提升了节目制作的画质和效果&#xff0c;还为节目制作带来了更高的效率和灵活性。那么4K超高清技术…

30多种独特艺术抽象液态酸性金属镀铬封面背景视觉纹理MOV视频素材

使用 Prismatic Flows 转换您的项目&#xff01;这个包拥有 30 多种独特的液体背景和动画&#xff0c;为任何创意活动提供令人惊叹的视觉效果。 棱镜流 – 动画背景和迭加包括30多种不同的液体背景和动画。这些高质量的资源非常适合通过充满活力和动态的视觉效果来增强您的项目…

概率论 期末 笔记

第一章 随机事件及其概率 利用“四大公式”求事件概率 习题 推导 全概率公式与贝叶斯公式 伯努利概型求概率 一维随机变量及其分布

VLAN数据格式

概念&#xff1a;VLAN叫做虚拟局域网&#xff0c;指在物理网络中根据用于、工作组、应用等进行逻辑划分的局域网&#xff0c;是一个广播域&#xff0c;与用户的物理位置没有关系。 作用&#xff1a;VLAN可以灵活的进行分段和组织&#xff0c;能够实现更好的安全性&#xff0c;…

计算机vcruntime140_1.dll丢失是什么原因?vcruntime140_1.dll丢失的解决办法如下:

计算机中vcruntime140_1.dll文件丢失的原因可能有多种&#xff0c;以下是一些常见的原因&#xff1a; 安装不完整或损坏&#xff1a;某些应用程序在安装过程中可能因为意外中断、安装程序损坏或其他原因导致vcruntime140_1.dll未能正确安装或复制到系统目录。软件卸载或更新不…

Redis学习(三)缓存

Redis学习&#xff08;三&#xff09;缓存 一、什么是缓存?如何使用缓存 二、添加商户缓存1、缓存模型和思路2、缓存更新策略1、数据库缓存不一致解决方案&#xff1a;2、数据库和缓存不一致采用什么方案 3、实现商铺和缓存与数据库双写一致 三、缓存穿透问题的解决思路1、编码…

软件设计与体系结构

1.简要说明什么是软件体系结构&#xff0c;软件体系结构模型&#xff0c;为什么要建立软件体系结构模型&#xff1f; 答&#xff1a;软件体系结构指一个软件系统在高层次上的结构化组织方式&#xff0c;包括系统的组成部分和各个部分之间的关系&#xff0c;以及它们与环境之间的…

Essential Use Cases和Real Use Cases

在软件开发领域&#xff0c;用例&#xff08;Use Cases&#xff09;是一种非常重要的工具&#xff0c;它能够帮助开发团队、产品经理以及用户之间对系统的功能需求达成一致。用例描述了在特定条件下&#xff0c;系统对用户请求所做出的响应&#xff0c;从而清晰地表达了系统的行…

概率论得学习和整理32: 用EXCEL描述正态分布,用δ求累计概率,以及已知概率求X的区间

目录 1 正态分布相关 2 正态分布的函数和曲线 2.1 正态分布的函数值&#xff0c;用norm.dist() 函数求 2.2 正态分布的pdf 和 cdf 2.3 正态分布的图形随着u 和 δ^2的变化 3 正态分布最重要的3δ原则 3.0 注意&#xff0c;这里说的概率一定是累计概率CDF&#xff0c;而…

使用开源在线聊天工具Fiora轻松搭建个性化聊天平台在线交流

文章目录 前言1.关于Fiora2.安装Docker3.本地部署Fiora4.使用Fiora5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime Kuma公网地址 前言 今天给大家介绍一款免费开源的在线聊天工具——Fiora。它不仅是一款功能强大的即时通讯软件&#xff0c;更是开发者们展现创造…

VS Code Copilot 与 Cursor 对比

选手简介 VS Code Copilot&#xff1a;算是“老牌”编程助手了&#xff0c;虽然Copilot在别的编辑器上也有扩展&#xff0c;不过体验最好的还是VS Code&#xff0c;毕竟都是微软家的所以功能集成更好一些&#xff1b;主要提供的是Complete和Chat能力&#xff0c;也就是代码补全…

Java Spring Boot 项目中嵌入前端静态资源:完整教程与实战案例

言简意赅的讲解Java Spring Boot 中嵌入前端项目的静态资源解决的痛点 之前给大家讲解了如何部署一个前端项目&#xff0c;但大家还是好奇如何部署一个前后端一体项目。将前端构建后的静态资源嵌入 Java Spring Boot 后端项目&#xff0c;是现代全栈开发中一种流行的实践方式。…

RabbitMQ中的Topic模式

在现代分布式系统中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个广泛使用的开源消息代理&#xff0c;支持多种消息传递模式&#xff0c;其中 Topic 模式 是一种灵活且强大的模式&#xff0c;允许生产者…

可编辑99PPT | 智能工厂整体规划方案及实施细部方案

荐言分享&#xff1a;智能工厂是利用物联网、大数据、人工智能等先进技术&#xff0c;实现生产过程自动化、智能化和柔性化的现代工厂。本整体规划方案旨在通过整合信息技术、自动化技术、人工智能技术和物联网技术&#xff0c;构建一个高效、灵活、绿色、可持续的生产环境&…

Day13 用Excel表体验梯度下降法

Day13 用Excel表体验梯度下降法 用所学公式创建Excel表 用Excel表体验梯度下降法 详见本Day文章顶部附带资源里的Excel表《梯度下降法》&#xff0c;可以对照表里的单元格公式进行理解&#xff0c;还可以多尝试几次不同的学习率 η \eta η来感受&#xff0c;只需要更改学习率…

YOLOv8改进,YOLOv8引入Hyper-YOLO的MANet混合聚合网络+HyperC2Net网络

摘要 理论介绍 MANet 的目标是通过多种卷积操作的协同作用,提高特征提取能力,并加强梯度流动,从而提升模型在不同层次的特征表示和语义深度。MANet 结合了三种卷积变体,通过混合使用它们来提高视觉特征的多样性和信息流动性。 HyperC2Net 的主要目标是通过超图结构对多层次…