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

ops/2025/3/17 20:26:43/

一、构造函数

构造函数是一种特殊的成员函数,主要用于创建对象时对对象进行初始化操作,即专门用于构造新对象,并赋值对象的成员数据。

在 C++ 里,构造函数的名称和类名相同,并且没有返回类型。当创建类的对象时,构造函数会自动被调用。

构造函数可以在类内也可在类外定义。

构造函数在类内的定义格式如下:

        类名(参数列表)

        {        函数体;        }

在类外定义构造函数的形式如下:

        类名::类名(形参列表)

        {        函数体;        }

构造函数可以重载,即可以有多个构造函数,因为构造函数有参数列表,构造函数一般为公有权限public。

定义对象时,系统会自动调用构造函数。同时若无主动定义,系统会自动生成一个默认的构造函数,该默认构造函数无参数,也不对数据成员初始化,仅为对象分配存储空间。如果显式地为类定义了构造函数,系统将不再为类提供默认构造函数。

#include <iostream>
using namespace std;
class Rectangle {
private:double length;double width;public:// 构造函数Rectangle(double l, double w) {length = l;width = w;}double getArea() {return length * width;}
};int main() {// 创建 Rectangle 对象并调用构造函数进行初始化Rectangle rect(5.0, 3.0);cout << "Rectangle area: " << rect.getArea() << endl;return 0;
}

1.默认构造函数

1.1系统自动生成默认构造函数

它只负责为对象分配存储空间,而不对数据进行初始化,一般为随机值。

1.2自定义默认构造函数

(1)默认参数只能最上面给,不能多处给定(避免不一致)
(2)带默认值的参数必须在最右面。
(3)有默认参数时,注意避免重定义。
上面三点和普通带默认值的函数一样。

2.构造函数的重载

在 C++ 中,构造函数的重载是指在一个类中可以定义多个具有相同名称(类名)但参数列表不同的构造函数。通过构造函数重载,我们可以使用不同的方式来初始化对象,以满足不同的需求。

构造函数重载的规则

  • 函数名相同:所有重载的构造函数的名称都必须与类名相同。
  • 参数列表不同:参数列表的不同可以体现在参数的个数、类型或顺序上。
  • 返回类型:构造函数没有返回类型,也不能使用void作为返回类型。
  • #include <iostream>
    #include <string>
    using namespace std;
    class Student {
    private:string name;int age;double score;public:// 默认构造函数Student() {name = "Unknown";age = 0;score = 0.0;cout << "Default constructor called." << endl;}// 带一个参数的构造函数,只初始化姓名Student(const string& n) {name = n;age = 0;score = 0.0;cout << "Constructor with one parameter called." << endl;}// 带两个参数的构造函数,初始化姓名和年龄Student(const string& n, int a) {name = n;age = a;score = 0.0;cout << "Constructor with two parameters called." <<endl;}// 带三个参数的构造函数,初始化姓名、年龄和分数Student(const string& n, int a, double s) {name = n;age = a;score = s;cout << "Constructor with three parameters called." << endl;}// 显示学生信息的函数void displayInfo() {cout << "Name: " << name << ", Age: " << age << ", Score: " << score << endl;}
    };int main() {// 使用默认构造函数创建对象Student s1;s1.displayInfo();// 使用带一个参数的构造函数创建对象Student s2("Alice");s2.displayInfo();// 使用带两个参数的构造函数创建对象Student s3("Bob", 20);s3.displayInfo();// 使用带三个参数的构造函数创建对象Student s4("Charlie", 22, 85.5);s4.displayInfo();return 0;
    }

3. 类定义时成员变量初始化

在C++11中允许在类定义时对成员变量初始化。

class A
{public:A(){ }void show(){cout << "m_a = " << m_a << endl;cout << "m_b = " << m_b << endl;}private:int m_a = 10;//类定义时初始化int m_b; //没有初始化
};int main()
{A a;a.show();return 0;
}

如果在构造函数中也有赋值,以赋值的为准,这个就和普通变量一样,初始化的值会被后面的赋值覆盖。

4.构造函数与初始化列表

构造函数也可以采用构造初始化列表的方式对数据成员进行初始化。

Date::Date(int y,int m,int d):year(y),month(m),day(d){}

二、析构函数

当对象的生存期结束时,系统就会自动执行析构函数回收其数据成员所分配的内存空间。

析构函数的定义格式为:

~类名();//没有返回值,没有参数

(1)析构函数名是由“~”加类名组成的。
(2)析构函数没有参数、没有返回值,不能重载。
(3)一个类有且仅有一个析构函数,必须为public。
(4)在对象的生存期结束时,由系统自动调用析构函数。
(5)如果没有定义析构函数,系统会自动生成一个默认的析构函数。

面试题:在main之前可以执行别的函数吗?在main结束后可以执行别的函数吗?

main函数之前执行函数

  • 可以通过使用全局对象的构造函数来实现。在程序启动时,全局对象会在main函数之前被初始化,其构造函数中的代码会在main函数之前执行。

main函数之后执行函数

  • 对于 C++ ,全局对象的析构函数会在main函数结束后执行,因为全局对象的生命周期在程序结束时才结束,所以析构函数中的代码可以在main函数之后执行。

三、构造和析构的调用顺序

先构造的后析构,后构造的先析构

当然函数和析构函数调用时机和它的生命周期是密不可分的。

下面归纳一下什么时候调用构造函数和析构函数。
(1)全局对象(生命周期:程序运行时创建,程序结束时销毁)的构造函数在所有函数(包括main函数)执行之前调用。但如果一个程序中有多个文件,而不同的文件中都定义了全局对象,则这些对象的构造函数的执行顺序是不确定的。当main函数执行完毕或调用exit函数时(此时程序终止),调用其析构函数。
(2)局部对象(在函数内定义的对象,其生命周期是进入该函数创建,函数退出结束)在进入该函数建立对象时调用其构造函数。如果函数被多次调用,则在每次建立对象时都要调用构造函数。在函数调用结束时调用析构函数。
(3)如果在函数中定义了静态(static)局部对象(生命周期是第一次进入该函数创建,程序退出时销毁),则只在程序第一次调用此函数建立对象时调用一次构造函数,在调用结束时对象并不被释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用析构函数。
(4)动态创建的对象,是调用new关键字创建函数时调用构造函数,调用delete函数销毁对象时调用析构函数


http://www.ppmy.cn/ops/166606.html

相关文章

Oracle Database 11g、12c、18c、19c、21c、22c 与 23AI 各版本差异、优缺点详解

Oracle Database 11g、12c、18c、19c、21c、22c 与 23AI 各版本差异、优缺点详解 Oracle Database 是全球领先的关系数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;在不断迭代的版本中引入新功能和优化&#xff0c;以满足企业级应用的多样化需求。本文将详细比较 O…

基于express+TS+mysql+sequelize的后端开发环境搭建

步骤一&#xff1a;初始化node环境 npm init -y 步骤二&#xff1a;安装 Express、TypeScript、以及相关类型的定义文件 npm install express npm install --save-dev typescript types/node types/express ts-node nodemon npm install body-parser npm install mysql2 npm in…

蓝桥杯刷题周计划(第三周)

目录 前言题目一题目代码题解分析 题目二题目代码题解分析 题目三题目代码题解分析 题目四题目代码题解分析 题目五题目代码题解分析 题目六题目代码题解分析 题目七题目代码题解分析 题目八题目代码题解分析 题目九题目代码题解分析 题目十题目代码题解分析 前言 大家好&#…

【R语言入门】向量,存储和计算

【R语言入门】向量&#xff0c;存储和计算 Vector, Storage and Computing by R Essentials By JacksonML 前文介绍了R的基本情况&#xff0c;完成了”Hello, world!”的交互式输出。 本文简要介绍R的向量&#xff0c;以及如何存储和进行简单数学计算&#xff0c;希望对R初学…

六种最新优化算法(TOC、MSO、AE、DOA、GOA、OX)求解多个无人机协同路径规划(可以自定义无人机数量及起始点),MATLAB代码

一、算法简介 &#xff08;一&#xff09;阿尔法进化&#xff08;Alpha Evolution&#xff0c;AE&#xff09;算法 阿尔法进化&#xff08;Alpha Evolution&#xff0c;AE&#xff09;算法是2024年提出的一种新型进化算法&#xff0c;其核心在于通过自适应基向量和随机步长的…

基于小波分析法的行波测距判断故障及定位故障Matlab仿真

微♥&#xff1a;“电击小子程高兴的MATLAB小屋”获取巨额优惠 1.模型简介 本仿真模型基于MATLAB/Simulink&#xff08;版本MATLAB 2017Ra&#xff09;软件。建议采用matlab2017 Ra及以上版本打开。&#xff08;若需要其他版本可联系代为转换&#xff09; 2.建模&#xff1a…

Vue3 Pinia $subscribe localStorage的用法 Store的组合式写法

Vue3 Pinia $subscribe 可以用来监视Stroe数据的变化 localStorage的用法 localStorage中只能存字符串&#xff0c;所有对象要选转成json字符串 定义store时&#xff0c;从localStorage中读取数据talkList可能是字符串也可能是空数组 Store的组合式写法 直接使用reactiv…

【NLP】10. 机器学习模型性能评估指标(含多类别情况), ROC,PRC

机器学习模型性能评估指标&#xff08;含多类别情况&#xff09; 1. 模型评估指标简介 在机器学习中&#xff0c;模型的性能评估非常重要。常用的模型评估指标有&#xff1a; 准确率&#xff08;Accuracy&#xff09;精度&#xff08;Precision&#xff09;召回率&#xff0…