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

c++:构造函数(Constructor)与析构函数(Destructor)

 

目录

 为什么我们需要构造函数?

什么是构造函数?

🧬 本质:构造函数是“创建对象的一部分” 

为什么 需要析构函数?

什么是析构函数?

析构函数的核心作用

❗注意点

为什么我们需要构造函数?

目的:在对象被创建(分配内存)时,自动初始化其成员变量,并完成一些必要的资源准备。 

核心本质:

  1. 构造函数 = 一种特殊的成员函数;

  2. 自动被调用,不能手动调用;

  3. 目的是保证对象在“出生”时是有效、完整的。

如果我们创建一个类 Person,它有名字和年龄两个成员变量。我们每次创建这个对象时都希望它是有意义的、状态合法的。 

class Person {
public:std::string name;int age;
};

如果你直接创建: 

Person p;

这样写当然是可以的,但是存在几个问题:

  1. 麻烦:每次创建都要写 .name = ....age = ...,很啰嗦。

  2. 容易出错:你可能忘记设置某个属性,比如只设置了名字,没有设置年龄。

  3. 没有保障:谁都可以创建一个“空白”的 Person,然后留下“脏数据”。

这会导致一大堆 bug。


什么是构造函数?

构造函数是一种特殊的函数,在你创建对象的时候,自动调用,用来进行初始化。

关键点:

  • 它和类同名。

  • 它没有返回值。

  • 它在对象创建的那一刻被调用(不是你手动调用,它自动来)。

  • 它的存在是为了:让对象一出生就是“有意义的、完整的”状态。

class Person {
public:std::string name;int age;// 构造函数Person(std::string n, int a) {name = n;age = a;}
};int main() {Person p("Alice", 30);  // ← 自动调用构造函数
}

你创建对象的时候,构造函数就被调用,把 name 和 age 初始化成你想要的值。 


 

🧬 本质:构造函数是“创建对象的一部分” 

你可以这样理解:

Person p("Alice",18);

这不是一句“函数调用”,而是: 

“我想创建一个叫 pPerson 类型的对象,它的初始状态是 name = "Alice"age = 30”。 

而构造函数的作用,就是: 

根据你提供的参数,决定这个对象“出生”时是什么样子。

所以构造函数是一种初始化的保证机制。 

 


为什么 需要析构函数?

C++ 是一门**“手动管理资源”**的语言(不像 Python、Java 有垃圾回收),也就是说: 

你创建了什么资源,就必须自己负责把它销毁。 

想象一个例子: 

class MyClass {
public:int* data;MyClass() {data = new int[100];  // 开辟了内存}
};

你用 new 分配了内存。

然后当你 main() 函数结束时,这个对象不再使用了。但那块 new 出来的内存还留在内存里!

这叫内存泄漏。

如果你每次都得自己写:

delete[] obj.data;

那太痛苦了,而且容易忘记。

于是 C++ 提供了解决方案:析构函数。


 

什么是析构函数?

析构函数是一个在对象“销毁”时自动调用的特殊函数。

它的作用是:在对象生命结束时,做一些清理工作,比如释放内存、关闭文件、断开连接等。 

  • 名字和类名相同,但前面有一个 ~(波浪号)。

  • 没有参数。

  • 没有返回值。

  • 不能重载(每个类只有一个析构函数)。

class MyClass {
public:int* data;MyClass() {data = new int[100];std::cout << "构造函数:分配内存" << std::endl;}~MyClass() {delete[] data;std::cout << "析构函数:释放内存" << std::endl;}
};int main() {MyClass obj; // 构造函数被调用
}               // 离开作用域,析构函数被自动调用

 

析构函数的核心作用

动作阶段你写的函数系统调用时机
对象创建构造函数new、定义变量时
对象销毁析构函数delete、变量离开作用域时

常见的清理操作包括:

  • delete 动态分配的内存

  • fclose() 关闭文件

  • 断开数据库连接

  • 打印日志(对象销毁时记录)


 

❗注意点

1. 自动对象 vs 动态对象

{MyClass a;  // 离开花括号,析构函数自动被调用
}MyClass* b = new MyClass();
// 只有当你 delete b; 析构函数才会被调用

所以:用 new 创建的对象必须手动 delete,否则析构函数不会执行!

2. 析构函数不能有参数,也不能重载

析构函数永远只有一个,不能像构造函数那样重载多个版本。

3. 析构函数可以是 virtual(虚析构)

virtual ~Base() {}

 如果你将来会用继承或多态,一定要写虚析构函数,否则可能导致资源无法正确释放(对象“表面”销毁了,内部派生类的资源没被释放)。

相关文章:

c++:构造函数(Constructor)与析构函数(Destructor)

目录 为什么我们需要构造函数&#xff1f; 什么是构造函数&#xff1f; &#x1f9ec; 本质&#xff1a;构造函数是“创建对象的一部分” 为什么 需要析构函数&#xff1f; 什么是析构函数&#xff1f; 析构函数的核心作用 ❗注意点 为什么我们需要构造函数&#xff1f…...

三周年创作纪念日

文章目录 回顾与收获三年收获的五个维度未来的展望致谢与呼唤 亲爱的社区朋友们&#xff0c;大家好&#xff01; 今天是 2025 年 4 月 14 日&#xff0c;距离我在 2022 年 4 月 14 日发布第一篇技术博客《SonarQube 部署》整整 1,095 天。在这条创作之路上&#xff0c;我既感慨…...

Vue 3 国际化实战:支持 Element Plus 组件和语言持久化

目录 Vue 3 国际化实战&#xff1a;支持 Element Plus 组件和语言持久化实现效果&#xff1a;效果一、中英文切换效果二、本地持久化存储效果三、element Plus国际化 vue3项目国际化实现步骤第一步、安装i18n第二步、配置i18n的en和zh第三步&#xff1a;使用 vue-i18n 库来实现…...

1.阿里云快速部署Dify智能应用

一、宝塔面板 宝塔面板是一款功能强大且易于使用的服务器管理软件&#xff0c;支持Linux和Windows系统&#xff0c;通过web端可视化操作&#xff0c;优化了建站流程&#xff0c;提供安全管理、计划任务、文件管理以及软件管理等功能。 1.1 宝塔面板的特点与优势 易用性 宝塔面…...

Ubuntu与windows时间同步

由于ubuntu每次重启后时间老是不对&#xff0c;所以使用ntp服务&#xff0c;让ubuntu作为客户端&#xff0c;去同步windows时间。 一、windows服务端配置 1、启用ntp服务 # 启动W32Time服务&#xff08;若未启动&#xff09; net start w32time # 配置服务为NTP模式 w32tm /…...

在pycharm配置虚拟环境和jupyter,解决jupyter运行失败问题

记录自己pycharm环境配置和解决问题的流程。 解决pycharm无法运行jupyter代码&#xff0c;仅运行import板块显示运行失败&#xff0c;但是控制台不输出任何错误信息&#xff0c;令人困惑。 遇到的问题是&#xff1a;运行代码左下角显示运行失败但是有没有任何的输出错误信息。 …...

Vue 技术解析:从核心概念到实战应用

Vue.js 是一款流行的渐进式前端框架&#xff0c;以其简洁的 API、灵活的组件化结构和高效的响应式数据绑定而受到开发者的广泛欢迎。本文将深入解析 Vue 技术的核心概念、原理和应用场景&#xff0c;帮助开发者更好地理解和使用 Vue.js。 一、Vue 的设计哲学与核心概念 &…...

Series和 DataFrame是 Pandas 库中的两种核心数据结构

Series 和 DataFrame 是 Pandas 库中的两种核心数据结构&#xff0c;它们各有特点和用途。理解它们之间的区别有助于更高效地进行数据分析和处理。以下是 Series 和 DataFrame 的主要区别&#xff1a; 1. 维度 Series&#xff1a;是一维的数组&#xff0c;可以存储任何类型的…...

关于异步消息队列的详细解析,涵盖JMS模式对比、常用组件分析、Spring Boot集成示例及总结

以下是关于异步消息队列的详细解析&#xff0c;涵盖JMS模式对比、常用组件分析、Spring Boot集成示例及总结&#xff1a; 一、异步消息核心概念与JMS模式对比 1. 异步消息核心组件 组件作用生产者发送消息到消息代理&#xff08;如RabbitMQ、Kafka&#xff09;。消息代理中间…...

利用 Python 进行股票数据可视化分析

在金融市场中&#xff0c;股票数据的可视化分析对于投资者和分析师来说至关重要。通过可视化&#xff0c;我们可以更直观地观察股票价格的走势、交易量的变化以及不同股票之间的相关性等。 Python 作为一种功能强大的编程语言&#xff0c;拥有丰富的数据处理和可视化库&#xf…...

【Docker】离线安装Docker

背景 离线安装Docker的必要性&#xff0c;第一&#xff0c;在目前数据安全升级的情况下&#xff0c;很多外网已经基本不好访问了。第二&#xff0c;如果公司有对外部署的需求&#xff0c;那么难免会存在对方只有内网的情况&#xff0c;那么我们就要做到学会离线安装。 下载安…...

kubectl命令补全以及oc命令补全

kubectl命令补全 1.安装bash-completion 如果你用的是Bash(默认情况下是)&#xff0c;先安装补全功能支持包 sudo apt update sudo apt install bash-completion -y2.为kubectl 启用补全功能 会话中临时&#xff1a; source <(kubectl completion bash)持久化配置&#x…...

《 C++ 点滴漫谈: 三十三 》当函数成为参数:解密 C++ 回调函数的全部姿势

一、前言 在现代软件开发中&#xff0c;“解耦” 与 “可扩展性” 已成为衡量一个系统架构优劣的重要标准。而在众多实现解耦机制的技术手段中&#xff0c;“回调函数” 无疑是一种高效且广泛使用的模式。你是否曾经在编写排序算法时&#xff0c;希望允许用户自定义排序规则&a…...

极简cnn-based手写数字识别程序

1.先看看识别效果&#xff1a; 这个程序识别的是0~9的一组手写数字&#xff0c;这是最终的识别效果&#xff0c;为1&#xff0c;代表识别成功&#xff0c;0为失败。 然后数据源是&#xff1a;ds deeplake.load(hub://activeloop/optical-handwritten-digits-train)里面是一组…...

C++核心机制-this 指针传递与内存布局分析

示例代码 #include<iostream> using namespace std;class A { public:int a;A() {printf("A:A()的this指针&#xff1a;%p!\n", this);}void funcA() {printf("A:funcA()的this指针&#xff1a;%p!\n", this);} };class B { public:int b;B() {prin…...

vue3 history路由模式刷新页面报错问题解决

在使用history路由模式时刷新网页提示404错误&#xff0c;这是改怎么办呢。 官方解决办法 https://router.vuejs.org/zh/guide/essentials/history-mode.html...

PHP爬虫教程:使用cURL和Simple HTML DOM Parser

一个关于如何使用PHP的cURL和HTML解析器来创建爬虫的教程&#xff0c;特别是处理代理信息的部分。首先&#xff0c;我需要确定用户的需求是什么。可能他们想从某个网站抓取数据&#xff0c;但遇到了反爬措施&#xff0c;需要使用代理来避免被封IP。不过用户没有提到具体的目标网…...

Web前端开发——格式化文本与段落(上)

一、学习目标 网页内容的排版包括文本格式化、段落格式化和整个页面的格式化&#xff0c;这是设计个网页的基础。文本格式化标记分为字体标记、文字修饰标记。字体标记和文字修饰标记包括对于字体样式的一些特殊修改。段落格式化标记分为段落标记、换行记、水平分隔线标记等。…...

技术方案选型要考虑哪些点?

在概要设计阶段&#xff0c;技术方案选型是核心环节之一&#xff0c;需综合考虑系统需求、技术可行性、团队能力及长期维护成本。以下是技术方案选型需包含的核心内容及设计要点&#xff0c;结合行业实践和搜索结果中的方法论&#xff1a; 理论 一、系统架构选型 整体架构模式…...

前端工程化之自动化构建

自动化构建 自动化构建的基本知识历史云构建 和 自动化构建 的区别&#xff1a;部署环境&#xff1a;构建&#xff1a;构建产物构建和打包的性能优化页面加载优化构建速度优化 DevOps原则反馈的技术实践 encode-bundlepackage.json解读src/cli-default.tssrc/cli-node.tssrc/cl…...

3.2.2.1 Spring Boot配置静态资源映射

在Spring Boot中配置静态资源映射&#xff0c;可以通过默认路径或自定义配置实现。默认情况下&#xff0c;Spring Boot会在classpath:/static/等目录下查找静态资源。若需自定义映射&#xff0c;可通过实现WebMvcConfigurer接口的addResourceHandlers方法或在全局配置文件中设置…...

# 更换手机热点后secureCRT无法连接centOS7系统

更换手机热点后secureCRT无法连接centOS7系统 一、问题描述 某些情况下&#xff0c;我们可能使用手机共享热点而给电脑联网。本来用一个手机热点共享网络时&#xff0c;SecureCRT可以正常连接到CentOS 7虚拟机&#xff0c;当更换一个手机热点时&#xff0c;突然发现SecureCR…...

【高性能缓存Redis_中间件】三、redis 精通:性能优化与生产实践

一、引言​ 在前两篇 Redis 消息队列的文章中&#xff0c;我们掌握了基础使用和高级特性。本文作为系列终篇&#xff0c;将聚焦生产环境的性能优化与全流程实践&#xff0c;请各位跟随小编的步伐一起构建高可靠、高性能的消息处理系统&#xff08;文章中的演示均为Centos7的背…...

jupyter notebook 无法启动- markupsafe导致

一、运行jupyter notebook和Spyder报错&#xff1a;(已安装了Anaconda&#xff0c;以前可打开) 1.背景&#xff1a;为了部署机器学习模型&#xff0c;按教程直接安装了flask 和markupsafe&#xff0c;导致jupyter notebook&#xff0c;Spyder 打不开。 pip install flas…...

Kotlin作用域函数

在 Kotlin 中&#xff0c;.apply 是一个 作用域函数&#xff08;Scope Function&#xff09;&#xff0c;它允许你在一个对象的上下文中执行代码块&#xff0c;并返回该对象本身。它的设计目的是为了 对象初始化 或 链式调用 时保持代码的简洁性和可读性。 // 不使用 apply va…...

设计模式:工厂方法模式 - 高扩展性与低耦合的设计之道

一、为什么需要工厂方法模式&#xff1f; 在软件开发中&#xff0c;对象创建与使用耦合会影响系统的灵活性和扩展性。以通知系统&#xff08;支持邮件通知、短信通知和推送通知&#xff09;为例 &#xff1a;直接实例化。 Notification email new EmailNotification(); Noti…...

CTF web入门之命令执行 完整版

web29 文件名过滤 由于flag被过滤,需要进行文件名绕过,有以下几种方法: 1.通配符绕过 fla?.* 2.反斜杠绕过 fl\ag.php 3.双引号绕过 fl’‘ag’.php 还有特殊变量$1、内联执行等 此外 读取文件利用cat函数,输出利用system、passthru 、echo echo `nl flag.php`; ec…...

自然语言处理spaCy

spaCy 是一个流行的开源 自然语言处理&#xff08;NLP&#xff09; 库&#xff0c;专注于 高效、易用和工业化应用。它由 Explosion AI 开发&#xff0c;广泛应用于文本处理、信息提取、机器翻译等领域。 zh_core_web_sm 是 spaCy 提供的一个小型中文预训练语言模型&#xff0…...

在spark中,窄依赖算子map和filter会组合为一个stage,这种情况下,map和filter是在一个task内进行的吗?

在 Spark 中&#xff0c;当 map 和 filter 这类窄依赖&#xff08;Narrow Dependency&#xff09;的算子连续应用时&#xff0c;它们会被合并到同一个 Stage 中&#xff0c;并且在同一个 Task 内按顺序执行。这种优化称为 流水线&#xff08;Pipeline&#xff09;执行&#xff…...

MySQL切换PolarDB-X方案

一、DTS 增量同步完成后的流量切换策略 1. 切换期间的数据写入处理 • 场景&#xff1a;DTS 增量同步完成&#xff08;Lag0&#xff09;后&#xff0c;业务流量切换到 PolarDB-X 的瞬间可能产生 2-3 秒延迟&#xff0c;导致部分订单仍写入 MySQL。 • 解决方案&#xff1a; ◦…...