C++析构函数和构造函数

一、构造函数


1.构造函数的基本概念

1.对构造函数的理解:

构造函数是类的一种特殊成员函数,其主要功能是在创建对象时进行初始化操作。它的名字与类名相同,并且没有返回值类型(不能是void)。例如,对于一个名为Rectangle的类,其构造函数可以写成Rectangle()或者Rectangle(int width, int height)等形式。

2.构造函数的调用:

每当创建一个类的对象时,相应的构造函数就会被自动调用。这是 C++ 中对象初始化的重要机制。例如:

     class Rectangle {
     public:
         int width;
         int height;
         Rectangle() {
             width = 0;
             height = 0;
         }
     };
     int main() {
         Rectangle rect;
         // 此时会自动调用Rectangle类的默认构造函数
         return 0;
     }

2.构造函数的类型

1.默认构造函数

1.定义:

如果一个类没有定义任何构造函数,编译器会自动为这个类生成一个默认构造函数。这个默认构造函数会对对象的基本类型成员进行默认初始化(对于内置类型,如intfloat等,其值是未定义的;对于类类型成员,会调用其自身的默认构造函数)。

2.自定义默认构造函数:

可以自己定义默认构造函数来明确对象的初始状态。例如:

       class Point {
       public:
           int x;
           int y;
           Point() : x(0), y(0) {}
       };

在这个Point类中,自定义的默认构造函数将xy都初始化为 0。


2.带参数的构造函数

1.定义:

这种构造函数接受参数,用于根据传入的参数值来初始化对象的成员变量。例如:

       class Circle {
       public:
           double radius;
           Circle(double r) : radius(r) {}
       };

 在这个Circle类中,构造函数Circle(double r)接受一个double类型的参数r,并将其赋值给成员变量radius,从而实现根据传入的半径值初始化Circle对象。

3.拷贝构造函数

1.定义:

用于通过一个已存在的同类型对象来初始化新的对象。它的形式通常是类名(const 类名& 源对象)。例如:

class String 
{
    public:
        char* data;
        String(const String& other) 
        {
            // 假设这里有合理的内存分配和字符串复制操作
            int length = strlen(other.data);
            data = new char[length + 1];
            strcpy(data, other.data);
        }
};

当执行String str1; String str2 = str1;这样的操作时,就会调用拷贝构造函数,将str1的内容复制到str2中。注意,这里只是一个简单示例,实际的字符串类还需要考虑内存管理等诸多细节。

2.构造函数的初始化列表
1.定义:

构造函数初始化列表是在构造函数的参数列表和函数体之间,以冒号开始的一系列成员初始化操作。例如:

class Complex 
{
     public:
         double real;
         double imag;
         Complex(double r, double i) : real(r), imag(i) {}
     };
2.优势:

使用初始化列表初始化成员变量通常比在构造函数体内赋值更高效。这是因为对于某些类型(如const成员变量和引用成员变量),只能通过初始化列表进行初始化。例如:

class ConstExample 
{
     public:
         const int value;
         ConstExample(int v) : value(v) {}
};

在这个ConstExample类中,value是一个const成员变量,必须通过初始化列表进行初始化,因为const成员变量一旦初始化后就不能再被赋值。

4.委托构造函数

1.定义:

委托构造函数是 C++ 11 引入的特性,它允许一个构造函数调用同一个类中的另一个构造函数,以避免代码重复。例如:

class Shape {
     public:
         int sides;
         Shape(int s) : sides(s) {}
         Shape() : Shape(0) {}
};

在这个Shape类中,默认构造函数Shape()委托给带参数的构造函数Shape(int s),将sides初始化为 0。


5. 转换构造函数

1.定义:

转换构造函数是一种特殊的单参数构造函数,它可以将参数类型隐式或显式地转换为类类型。例如:

class Temperature
{
     public:
         double value;
         Temperature(double v) : value(v) {}
};

int main() 
{

    double tempValue = 25.0;
    Temperature temp(tempValue);
    // 或者可以隐式转换(如果允许)
    Temperature temp2 = 30.0;
    return 0;
}

在这个Temperature类中,构造函数Temperature(double v)可以将double类型的值转换为Temperature类的对象,既可以像Temperature temp(tempValue)这样显式转换,也可以在允许隐式转换的情况下像Temperature temp2 = 30.0这样使用。不过,过度使用隐式转换可能会导致代码的可读性和可维护性变差,需要谨慎使用。


二、析构函数(目前我觉得理解到这部分其实已经够了)

  • 析构函数是类的一种特殊成员函数,它的名字是在类名前面加上 “~” 符号。析构函数没有参数,也没有返回值类型。例如,对于类MyClass,其析构函数为~MyClass()
  • 析构函数的主要作用是在对象销毁时执行清理操作,比如释放对象在生命周期内动态分配的内存、关闭文件、释放网络连接等资源。
  • 当对象的生命周期结束时,析构函数会自动被调用。
    • 例如,对于局部对象,当它所在的函数执行完毕返回时,对象的析构函数就会被调用;
    • 对于通过new创建的动态对象,当使用delete删除该对象时,析构函数会被调用。
#include<string>
#include<iostream>
using namespace std;
class Student
{
	public:
		Student(int n,string nam,string s)//定义有参的构造偶函数
		{
			num = n;
			name = nam;
			sex = s;
			cout << "构造函数被调用" << endl;//输出有关信息	
		} 
		~Student()
		{
			cout << "析构函数被调用" << endl;//输出有关信息 
		}
		void display()
		{
			cout << "num:" << num << endl;
			cout << "name:" << name << endl;
			cout << "sex:" << sex << endl << endl;
		}
		
	private:
		int num;
		string name;
		string sex;
};

int main()
{
	Student stud1(10010,"张三","男");//建立对象stu1
	stud1.display();
	Student stud2(10011,"李华","女");//建立对象stu2
	stud2.display(); 
	
	return 0;
}

程序运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【python自动化四】日志打印

我们在进行自动化测试时&#xff0c;需要打印过程日志和结果日志等&#xff0c;这里记录下日志的相关配置。这里我们直接自己新建一个logger。 先贴上日志代码如下&#xff0c;可根据需要修改&#xff1a; import logging import os import timefrom logging.handlers import …

鸿蒙分享(一):添加模块,修改app名称图标

码仓库&#xff1a;https://gitee.com/linguanzhong/share_harmonyos 鸿蒙api:12 新建公共模块common 在entry的oh-package.json5添加dependencies&#xff0c;引入common模块 "dependencies": {"common": "file:../common" } 修改app名称&…

IDE如何安装插件实现Go to Definition

项目背景 框架&#xff1a;Cucumber Cypress 语言&#xff1a;Javascript IDE&#xff1a;vscode 需求 项目根目录cypress-automation的cypress/integration是测试用例的存放路径&#xff0c;按照不同模块不同功能创建了很多子目录&#xff0c;cucumber测试用例.feature文…

【机器学习】CatBoost 模型实践:回归与分类的全流程解析

一. 引言 本篇博客首发于掘金 https://juejin.cn/post/7441027173430018067。 PS&#xff1a;转载自己的文章也算原创吧。 在机器学习领域&#xff0c;CatBoost 是一款强大的梯度提升框架&#xff0c;特别适合处理带有类别特征的数据。本篇博客以脱敏后的保险数据集为例&#x…

HTML Input 文件上传功能全解析:从基础到优化

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Unity在运行状态下,当物体Mesh网格发生变化时,如何让MeshCollider碰撞体也随之实时同步变化?

旧版源代码地址&#xff1a;https://download.csdn.net/download/qq_41603955/90087225?spm1001.2014.3001.5501 旧版效果展示&#xff1a; 新版加上MeshCollider后的效果&#xff1a; 注意&#xff1a;在Unity中&#xff0c;当你动态地更改物体的Mesh时&#xff0c;通常期望…

conda create -n name python=x.x 执行失败问题解决方法

今天想在anaconda环境下创建一个指定python版本为3.9的虚拟环境&#xff0c;执行命令 conda create -n DeepLearning python3.9 但是系统竟然报错 看报错信息是在镜像源里找不到下载包&#xff0c;于是对镜像源文件处理 首先删除之前的镜像通道 conda config --remove-key …

第一个 JSP 程序

一个简单的 JSP 程序&#xff1a; 使用 IDEA 开发工具新建一个 maven 项目&#xff0c;具体操作如图所示&#xff1a; 配置 Tomcat 服务器 项目结构如下图所示&#xff1a; 3. 修改 index.jsp 页面的代码&#xff1a; <% page language"java" contentType&q…

Altium Designer学习笔记 32 DRC检查_丝印调整

基于Altium Designer 23学习版&#xff0c;四层板智能小车PCB 更多AD学习笔记&#xff1a;Altium Designer学习笔记 1-5 工程创建_元件库创建Altium Designer学习笔记 6-10 异性元件库创建_原理图绘制Altium Designer学习笔记 11-15 原理图的封装 编译 检查 _PCB封装库的创建Al…

docker学习笔记(五)--docker-compose

文章目录 常用命令docker-compose是什么yml配置指令详解versionservicesimagebuildcommandportsvolumesdepends_on docker-compose.yml文件编写 常用命令 命令说明docker-compose up启动所有docker-compose服务&#xff0c;通常加上-d选项&#xff0c;让其运行在后台docker-co…

不同类型的集成技术——Bagging、Boosting、Stacking、Voting、Blending简述

目录 一、说明 二、堆叠 2.1 堆叠的工作原理&#xff1a; 2.2 例子&#xff1a; 2.3 堆叠的优点&#xff1a; 三、投票&#xff08;简单投票&#xff09; 3.1 例子&#xff1a; 3.2 投票的优点&#xff1a; 四、装袋和投票之间的区别 五、混合 6.1 混合的主要特征&#xff1a; …

ONES 功能上新|ONES Project 甘特图再度升级

ONES Project 甘特图支持展示工作项标题、进度百分比、依赖关系延迟时间等信息。 应用场景&#xff1a; 在使用甘特图规划项目任务、编排项目计划时&#xff0c;可以对甘特图区域进行配置&#xff0c;展示工作项的工作项标题、进度百分比以及依赖关系延迟时间等维度&#xff0c…

【目标检测】【反无人机目标检测】使用SEB-YOLOv8s实时检测未经授权的无人机

Real-Time Detection of Unauthorized Unmanned Aerial Vehicles Using SEB-YOLOv8s 使用SEB-YOLOv8s实时检测未经授权的无人机 论文链接 0.论文摘要 摘要&#xff1a;针对无人机的实时检测&#xff0c;复杂背景下无人机小目标容易漏检、难以检测的问题。为了在降低内存和计算…

Elasticsearch:使用 Elastic APM 监控 Android 应用程序

一、前言 人们通过私人和专业的移动应用程序在智能手机上处理越来越多的事情。 拥有成千上万甚至数百万的用户&#xff0c;确保出色的性能和可靠性是移动应用程序和相关后端服务的提供商和运营商面临的主要挑战。 了解移动应用程序的行为、崩溃的发生和类型、响应时间慢的根本…

DataSophon集成CMAK KafkaManager

本次集成基于DDP1.2.1 集成CMAK-3.0.0.6 设计的json和tar包我放网盘了. 通过网盘分享的文件&#xff1a;DDP集成CMAK 链接: https://pan.baidu.com/s/1BR70Ajj9FxvjBlsOX4Ivhw?pwdcpmc 提取码: cpmc CMAK github上提供了zip压缩包.将压缩包解压之后 在根目录下加入启动脚本…

Java——异常机制(上)

1 异常机制本质 (异常在Java里面是对象) (抛出异常&#xff1a;执行一个方法时&#xff0c;如果发生异常&#xff0c;则这个方法生成代表该异常的一个对象&#xff0c;停止当前执行路径&#xff0c;并把异常对象提交给JRE) 工作中&#xff0c;程序遇到的情况不可能完美。比如…

vue3 vite ts day2

虚拟dom diff 算法的了解 diff 算法 源码的了解 简单易懂的图 参考文章 学习Vue3 第五章&#xff08;Vue核心虚拟Dom和 diff 算法&#xff09;_学习vue3 第五章 (vue核心虚拟dom-CSDN博客 如需了解更多请去原作者下看&#xff0c;讲的真的很细。 ref reactive vue2 …

动态计算加载图片

学习啦 别名路径&#xff1a;①npm install path --save-dev②配置 // vite.config,js import { defineConfig } from vite import vue from vitejs/plugin-vueimport { viteStaticCopy } from vite-plugin-static-copy import path from path export default defineConfig({re…

Postgresql 格式转换笔记整理

1、数据类型有哪些 1.1 数值类型 DECIMAL/NUMERIC 使用方法 DECIMAL是PostgreSQL中的一种数值数据类型&#xff0c;用于存储固定精度和小数位数的数值。DECIMAL的精度是由用户指定的&#xff0c;可以存储任何位数的数值&#xff0c;而小数位数则由用户自行定义。DECIMAL类型的…

爬虫运行后数据如何存储?

爬虫运行后获取的数据可以存储在多种不同的存储系统中&#xff0c;具体选择取决于数据的规模、查询需求以及应用场景。以下是一些常见的数据存储方法&#xff1a; 1. 文件系统 对于小型项目或临时数据存储&#xff0c;可以直接将数据保存到本地文件中。常见的文件格式包括&…