深入理解构造函数: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"; …

后端项目java中字符串、集合、日期时间常用方法

我这里只介绍了项目中最常用的哈,比如像集合有很多,但我们最常用的就是ArrayList。 然后我这里会以javascript中的字符串、数组的方法为基准来实现,有些方法js和java会有些区别也会介绍 字符串 每次修改 String 对象都会创建一个新的对象,而 StringBuffer 可以在同一个对象…

Ubuntu 22.04永久保存路由

在 Ubuntu 22.04 上&#xff0c;可以按照以下方式配置让流量访问 172.19.201.207 走指定的路由。 1. 临时添加路由 临时路由规则只在当前系统会话中有效&#xff0c;重启后会丢失。 添加路由规则 运行以下命令&#xff1a; sudo ip route add 172.19.201.207 via 192.168.2…

实用 Linux 之命令(Practical Linux Commands)

实用 Linux之 命令&#xff0c;可以解决日常99%的问题~ 1、基本命令 uname -m 显示机器的处理器架构uname -r 显示正在使用的内核版本dmidecode -q 显示硬件系统部件(SMBIOS / DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性hdparm -tT /dev/sda 在磁盘上执行测试性读取操作…

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多种不同的液体背景和动画。这些高质量的资源非常适合通过充满活力和动态的视觉效果来增强您的项目…

32. 线程、进程与协程

一、什么是多任务 如果一个操作系统上同时运行了多个程序&#xff0c;那么称这个操作系统就是 多任务的操作系统&#xff0c;例如&#xff1a;Windows、Mac、Android、IOS、Harmony 等。如果是一个程序&#xff0c;它可以同时执行多个事情&#xff0c;那么就称为 多任务的程序。…

概率论 期末 笔记

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

VLAN数据格式

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

css 裁剪 clip-path

clip-path 是一个强大的 CSS 属性&#xff0c;用于裁剪元素的可视区域&#xff0c;支持多种形状裁剪。它可以用来创建复杂的裁剪效果&#xff0c;如圆形、多边形、路径等。 clip-path: none | shape | url(#clipPathId);none&#xff1a;不裁剪&#xff0c;显示完整内容。shap…

*【每日一题 基础题】 [蓝桥杯 2023 省 B] 飞机降落

题目描述 N 架飞机准备降落到某个只有一条跑道的机场。其中第 i 架飞机在 Ti 时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 Di 个单位时间&#xff0c;即它最早可以于 Ti 时刻开始降落&#xff0c;最晚可以于 Ti Di 时刻开始降落。降落过程需要 Li个单位时间…

计算机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;从而清晰地表达了系统的行…

P102如何降频降压

要对NVIDIA P102显卡进行降频降压操作&#xff0c;可以按照以下步骤进行&#xff1a; • 使用MSI Afterburner软件&#xff1a; • 打开MSI Afterburner&#xff0c;使用曲线编辑器调整频率和电压。竖轴为核心频率&#xff0c;横轴为电压。通过整体下移靠后的频率和电压区域&a…

概率论得学习和整理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;而…