【C++】- 类和对象(构造函数!析构函数!拷贝构造函数!详解)

类和对象②

  • 类的6个默认成员函数
  • 构造函数
  • 析构函数
  • 拷贝构造函数

类的6个默认成员函数

上一篇详细介绍了类。如果一个类中什么成员都没有,简称为空类。

在这里插入图片描述那么空类中真的什么都没有吗?

并不是,当类在什么都不写时,编译器会自动生成以下6个默认成员函数:

  • 默认构造函数:如果一个类没有定义任何构造函数,编译器会自动生成一个默认构造函数。默认构造函数不带参数,用来初始化对象的非静态成员变量。
  • 拷贝构造函数:拷贝构造函数用于按值传递参数或以值返回对象时调用,也可以用于复制一个对象到另一个对象。默认的拷贝构造函数将每个成员变量从另一个对象复制到新对象中。
  • 赋值运算符:赋值运算符用于将一个对象的值赋给另一个对象。默认的赋值运算符将每个成员变量从另一个对象复制到当前对象中。
  • 移动构造函数:移动构造函数用于转移对象内存资源的所有权。当使用右值引用时,可以调用移动构造函数。
  • 移动赋值运算符:移动赋值运算符用于将对象内存资源的所有权转移给另一个对象。当使用右值引用时,可以调用移动赋值运算符。
  • 析构函数:析构函数用于在对象被销毁时进行清理工作,如释放动态分配的内存。默认的析构函数不做任何操作

构造函数

在面向对象的编程语言中,构造函数是一种特殊的成员函数,用于创建和初始化对象。构造函数在对象创建时自动调用,并且在对象整个生命周期内只调用一次。负责为对象分配内存并对成员变量进行初始化。

构造函数是一个与类同名的特殊成员函数,没有返回类型,并在对象创建时自动调用。它的作用是初始化对象的数据成员,为对象分配内存空间,并执行其他必要的初始化操作。

在这里插入图片描述构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。

每个类都至少有一个构造函数,如果没有显式定义,编译器会自动生成默认构造函数。

看下面一段代码:

#include <iostream>
using namespace std;

// 定义一个简单的Person类
class Person {
private:
    string name;
    int age;

public:
    // 默认构造函数
    Person() {
        name = "Unknown";
        age = 0;
        cout << "Default constructor called" << endl;
    }

    // 带参数的构造函数
    Person(string n, int a) {
        name = n;
        age = a;
        cout << "Parameterized constructor called" << endl;
    }

    // 打印信息的成员函数
    void printInfo() {
        cout << "Name: " << name << endl;
        cout << "Age: " << age << endl;
    }
};

int main() {
    // 创建对象并调用默认构造函数
    Person p1;   // 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
    p1.printInfo();
    
    // 创建对象并调用带参数的构造函数
    Person p2("Alice", 25);
    p2.printInfo();

    return 0;
}

在上述示例代码中,我们定义了一个名为Person的类,该类具有两个构造函数:默认构造函数带参数的构造函数。默认构造函数在对象创建时自动调用,对name和age进行默认初始化,并输出一条相关信息。带参数的构造函数接受两个参数(姓名和年龄),并将其赋值给相应的成员变量,同样输出一条相关信息

所以上面代码的运行结果是:

Default constructor called
Name: Unknown
Age: 0
Parameterized constructor called
Name: Alice
Age: 25

在这里对编译器生成的默认构造函数作说明:
在这里插入图片描述

析构函数

在面向对象的编程中,析构函数是一种特殊类型的函数,用于在对象生命周期结束时执行清理和释放资源的操作。与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。

析构函数的作用:

  • 释放资源:析构函数常用于释放对象在生命周期中申请的动态内存、关闭文件或网络连接等资源。
  • 清理操作:析构函数可用于执行对象销毁前需要进行的清理操作。

析构函数的命名和特点:

  1. 析构函数与类名相同,前面加上一个波浪号 ~ 作为标识符。
  2. 析构函数无返回类型,无参数(或者带有默认参数),无返回值类型,且只能有一个析构函数。
  3. 析构函数不能被继承,因此不能被声明为虚函数。
  4. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构
    函数不能重载

析构函数的调用时机:

  • 当对象的生命周期结束时,即对象超出其作用域。
  • 当对象被显式删除(delete)或销毁(destroy)时。
  • 当对象是动态分配的,且所在的内存被释放时。

看下面一段代码

class MyClass {
private:
    int* ptr;

public:
    MyClass() {
        ptr = new int;
        *ptr = 0;
    }

    ~MyClass() {
        delete ptr;
        cout << "Destructor called" << endl;
    }
};

int main() {
    MyClass obj;
    // ...
    return 0;
}

在上述示例代码中,MyClass类的析构函数负责释放动态分配的内存,它会在对象生命周期结束时自动被调用。

1.析构函数应该遵循“先进后出”的原则。即,如果在构造函数中有动态分配的资源,那么在析构函数中应该按相反的顺序释放这些资源。
2.析构函数不应该抛出异常,因为在析构函数中抛出异常会导致程序崩溃。
3.在继承关系中,基类的析构函数应该声明为虚函数,以确保派生类对象能够正确地释放资源。

拷贝构造函数

拷贝构造函数是一个特殊的构造函数,用于创建一个对象并将其初始化为同类对象的副本。当对象被作为参数传递给函数或者通过赋值操作符进行对象之间的赋值时,拷贝构造函数被自动调用。它通常采用引用方式传递对象参数,并且参数必须是const类型,以避免修改原始对象的值。

拷贝构造函数的语法如下:

ClassName(const ClassName& obj);

拷贝构造函数经常的使用场景:

  1. 对象作为函数参数传递:当对象作为函数参数传递时,拷贝构造函数会被调用来创建一个新对象,并将原始对象的值复制到新对象中。这样可以确保函数内部对对象的修改不会影响到原始对象。
  2. 对象作为函数返回值:当函数返回一个对象时,拷贝构造函数用于创建返回值的副本。这样可以避免在函数返回后原始对象被修改导致错误的结果。
  3. 对象之间的赋值操作:当将一个对象赋值给另一个对象时,拷贝构造函数会被调用来创建一个副本。这样可以确保新对象独立于原始对象,修改新对象不会影响到原始对象

拷贝构造函数可以实现两种类型的拷贝:深拷贝浅拷贝.

深拷贝:深拷贝会创建一个新的对象,并将原始对象中的所有成员变量逐个复制到新对象中。这样每个对象都有自己的独立内存空间,修改一个对象不会影响到其他对象。

浅拷贝:浅拷贝只是简单地复制指针,两个对象共享同一块内存空间。这意味着,如果一个对象修改了共享的内存,另一个对象的值也会发生改变。

在拷贝构造函数中,如果成员变量包含指针或动态分配的内存,我们应该采用深拷贝,确保每个对象都有自己的独立内存空间。

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

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

相关文章

Mac 16g约等于Windows多少g?

Mac 16g 内存等于 Windows 320g 内存 何为“黄金内存”&#xff1f; Mac 的内存是用黄金做的&#xff0c;而 Windows 的内存是用铁做的。 黄金的密度是 19.32 g/cm&#xff0c;而铁的密度是 7.874 g/cm。 因此&#xff0c;16g 的黄金体积是 0.082 cm&#xff0c;而 16g 的铁…

CentOS设置docker静态ip

docker容器的ip地址在每次启动后启动顺序设置ip地址&#xff0c;为解决ip地址变动的问题&#xff0c;我们有必要设置docker内部ip地址固定。 第一步先创建一个本地ip地址固定容器的ip docker network create —driver bridge —subnet172.18.12.0/16 —gateway172.18.1.1 wn_d…

XCTF-Misc1 USB键盘流量分析

m0_01 附件是一个USB流量文件 分析 1.键盘流量 USB协议数据部分在Leftover Capture Data域中&#xff0c;数据长度为八个字节&#xff0c;其中键盘击健信息集中在第三个字节中。 usb keyboard映射表&#xff1a;USB协议中HID设备描述符以及键盘按键值对应编码表 2.USB…

【SpringCloud Alibaba笔记】(2)Sentinel实现熔断与限流

Sentinel 概述 官网&#xff1a;https://github.com/alibaba/Sentinel 中文文档&#xff1a;https://sentinelguard.io/zh-cn/docs/introduction.html 类似Hystrix&#xff0c;以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热…

w18认证崩溃之暴力破解DVWA

一、实验环境 攻击工具&#xff1a;burpsuite2021.12 靶场&#xff1a;DVWA二、实验目的 演示暴破DVWA的medium和high两个级别&#xff0c;low级别请查看w18认证崩溃之暴力破解4种攻击模式 三、实验步骤 1.设置靶场medium级别 2.开启谷歌代理插件&#xff0c;开启bp拦截&…

多时点DID

标准 DID 模型一般针对政策实施时点为同一个时期&#xff0c;且接受干预的状态将一直持续下去&#xff0c;否则 的交互项设置将会严重违背平行趋势的假设&#xff0c;从而导致交互项的估计系数有偏。由于现实世界中很多的政策试点地区和时间都不尽相同&#xff0c;而且也容易发…

霍兰德职业兴趣测试 60题(免费版)

霍兰德职业兴趣理论从兴趣的角度出发探索职业指导的问题&#xff0c;明确了职业兴趣的人格观念&#xff0c;使得人们对于职业兴趣的认识有了质的变化。在霍兰德职业兴趣理论提出来之前&#xff0c;职业兴趣和职业环境二者分别独立存在&#xff0c;正是霍兰德的总结&#xff0c;…

test dbtest-00-数据库测试

拓展阅读 DbUnit-01-数据库测试工具入门介绍 database tool-01-flyway 数据库迁移工具介绍 数据库测试一直是一个痛点&#xff0c;测试的时候如何针对数据库测试呢? 数据库测试是确保数据库系统正确性、性能和可靠性的重要环节。以下是一些建议&#xff0c;可帮助您有效地…

跟着小德学C++之安全模块

嗨&#xff0c;大家好&#xff0c;我是出生在达纳苏斯的一名德鲁伊&#xff0c;我是要立志成为海贼王&#xff0c;啊不&#xff0c;是立志成为科学家的德鲁伊。最近&#xff0c;我发现我们所处的世界是一个虚拟的世界&#xff0c;并由此开始&#xff0c;我展开了对我们这个世界…

PPT模板(100套IT科技互联网风)

哈喽&#xff0c;小伙伴们&#xff0c;最近是不是都在准备年终总结、年终述职&#xff0c;一个好的PPT模板是编写报告的开端。我最近也在准备年终总结报告&#xff0c;一块整理了一些PPT模板。这些模板适用于各种IT科技互联网相关的场合&#xff0c;如产品发布会、项目提案、工…

Python和Java环境搭建

小白搭建全流程 首先不建议装在C盘&#xff0c;一旦重置电脑&#xff0c;之前安装第三方包需要重新安装 relolver :解释器 1、Python解释器安装 资源包&#xff1a; 1、 python -version java -version–用于查看是否安装 where python whrer java–用于查看安装的位置【非常…

【数据库】聊聊常见的索引优化-下

分页查询优化 主键排序 在实际的使用中&#xff0c;通过limit 10000,10 查询第10000记录到10010记录&#xff0c;mysql执行的时候是按照将前10010记录全部统计出来&#xff0c;然后剔除前10000条记录&#xff0c;选择后10条记录。这样来看的话&#xff0c;效率不高。 如果数据…

【C++】upper_bound和lower_bound

一个是返回第一个大于等于val的element的iter&#xff0c;另一个是返回第一个大于val的element的iter

2024年如何跻身前1%?

2024年如何跻身前1%&#xff1f; 8个习惯助你成为更好的自己 随着2023年即将结束&#xff0c;大家都在为2024年定下目标、列出清单并下定决心。新的一年不仅是结束和告别旧的自己、犯过的错误以及失败的战斗&#xff0c;也是期待着新的开始。 如果你也希望超越困境&#xff…

buuctf-Misc 题目解答分解109-111

109.[CFI-CTF 2018]webLogon capture 流量包分析&#xff0c; wireshark 打开 就这几个数据包&#xff0c;追踪http 进行url 解码 URL网址解码器 - 在线网址解码 得到flag CFI{1ns3cur3_l0g0n} 110.[GKCTF 2021]excel 骚操作 下载 excel 文件 &#xff0c;打开 发现点击其他地…

vue结合Cesium加载gltf模型

Cesium支持什么格式&#xff1f; Cesium支持的格式包括&#xff1a;3D模型格式&#xff08;如COLLADA、gITF、OBJ&#xff09;、影像格式&#xff08;如JPEG、PNG、GeoTIFF&#xff09;、地形格式&#xff08;如STL、Heightmap&#xff09;、矢量数据格式&#xff08;如GeoJSON…

CSS基础笔记-04cascade-specificity-inheritance

CSS基础笔记系列 《CSS基础笔记-01CSS概述》《CSS基础笔记-02动画》CSS基础笔记-03选择器 前言 Cascading Style Sheets&#xff0c;关键就在于这个cascading&#xff0c;对于这个术语理解&#xff0c;感觉对于我这种CSS新手有点儿不太friendly。本文记录下我对这个术语的理…

二叉树的经典算法(算法村第八关青铜挑战)

二叉树里的双指针 所谓的双指针就是定义了两个变量&#xff0c;在二叉树中有需要至少定义两个变量才能解决问题。这两个指针可能针对一棵树&#xff0c;也可能针对两棵树&#xff0c;姑且也称之为“双指针”。这些问题一般与对称、反转和合并等类型题相关。 判断两棵树是否相…

1- forecasting at scale论文阅读

目录 1. 什么是时间序列2. 什么是时间序列预测3. 时间序列预测的范式4. 时间序列的专有名词介绍5. 时间序列评估 1. 什么是时间序列 按时间先后顺序出现的有序序列 2. 什么是时间序列预测 点预测&#xff1a;预测未来的某一个时间点&#xff0c;它的值到底是多少&#xff0c…

高效管理文件方法:每4个文件前面加序号,4个文件后面又单独编号技巧

在日常工作中&#xff0c;文件管理是一项常见的任务。要更高效地管理文件&#xff0c;可以通过在每个文件前面加序号&#xff0c;并在每个序号对应的文件后面进行单独编号的方法来实现。这种方法有助于快速找到所需文件&#xff0c;也能提高工作效率。下面一起来看下云炫文件管…