构造函数与析构函数

C++ 构造函数与析构函数 作用:初始化对象,在对象创建时自动调用,用于分配资源、设置初始值。特性用途关键点默认构造函数无参初始化对象可自动生成,但若定义其他构造需显式声明拷贝构造函数深拷贝动态资源避免浅拷贝导致重复释放移动构造函数高效转移资源(C++11)使用std::move触发析构函数释放资源(内存、文件等)虚析构函数确保多态安全explicit禁止隐式类型转换防止意外构造初始化列表高效初始化成员必须用于const或引用成员最佳实践优先使用初始化列表。多态基类必须声明虚析构函数。 阅读详情

概述:一个类有两种特殊的成员函数:构造函数与析构函数。构造函数功能是在创建对象时,给数据成员赋初值,即对象的初始化。析构函数的功能是释放一个对象,在对象删除前,用它做一些内存释放工作,与构造函数的功能相反。


构造函数:在对象建立时它会被自动执行,因此变量、对象的初始化代码一般都放在构造函数中。

  (1)对象的初始化过程

先看程序中变量、数组、结构变量和对象的初始化过程。

在C++中,变量初始化有以下两种等价形式:

  int a(5);      //C++初始化形式

  int b=8;      //C初始化形式

    定义时初始化的目的是在编译时为变量开辟内存空间的同时将初始值写入内存空间。

数组初始化:只有 ” ={处置列表} “ 这种形式。例如下列代码

   double c[] = { 1,2,3,4};

等价于下列赋值语句

  c[[0]=1; c[1]=2; c[3]=3; c[4]=4;

        结构变量初始化: 也使用 ” ={初值列表} “这种形式,代码如下:

struct  PERSON

{

char   name[20];    //姓名

float   height;        //身高

float   weight;       //体重

};

PERSON one={"DONG", 170, 130};

等价于下列赋值语句

strcpy(one.name, "DONG");   one.height=170;  one.weight=130;

struct中各成员的默认访问权限是public,因此上述初始化操作是合法的。类的对象有所不同

类对象初始化:

class  CPerson

{

char  name[20];     //姓名

float  height;          //身高

float  weight;         //体重

}

CPerson  one={ "DONG", 170, 130};  //错误的赋值方式,

  等价于赋值方式: strcpy(one.name, "DONG");  one.height=170;  one.weight=130;

  因为类中的数据成员默认都是private的,无法通过对象one来访问私有数据成员。可以将class各成员访问权限             设置为public,这样效果等同于struct,却降低了类的封装性。

类对象的数据成员初始化是通过类的成员函数来完成的

 class  CPerson

{

public:

void setValue(char *str, float h, float w)

{

strcpy(name,str);  height = h;  weight=w;

}

private:

char  name[20]; 

float  height;

float  weight;

};

于是:CPerson  one;     one.setValue("DONG", 170, 130);  // A: 调用成员函数设置初始值

A 语句通过调用成员函数来设定对象one的数据成员初始值,并非是对象的初始化格式。

一个对象的初始化是指在定义的同时赋初值.

       一个类可以看成是一个整体类型,类似于C++内建的基本类型int、char、float、double等。

对象初始化可以有:CPerson  one( "DONG", 170, 130);

对象初始化不一定要对所有的数据成员进行初始化,还可以有:

CPerson  one("DONG", 170, 130);

CPerson  one(170, 130);

CPerson  one;

为了实现以上形式的对象初始化操作,需要使用类的构造函数(Constructor)。


(2)构造函数

C++规定,一个类的构造函数必须与类同名,它可带参数也可不带参数,可以重载,也可以有默认的形参值。

上述对象初始化形式就是对象相应版本对构造函数的调用。例如:

one.CPerson("DONG", 170, 130);

one.CPerson(170, 130);

one.CPerson();

1、构造函数名必须与类名相同 2、定义的构造函数不能指定其返回值类型,也不能指定为void类型,构造函数主要是用于对象数据成员初始化,因而无须返回函数值,也就无须又返回类型。3、若要定义类对象,构造函数必须是公有型成员函数,否则,类无法实例化。若类仅用于派生其他类,则构造函数可定义为保护型成员函数。

        4、构造函数重载或设定构造函数默认形参值时,避免二义性。例如:

CPerson(char *str, float h=170, float w=130) // A

{

strcpy(name, str);  height=h;  weight=w;

        }

CPerson(char *str)   // B

{

strcpy(name, str);

}

     当 CPerson  other(" DONG "); 时,即 other.CPerson("DONG");此时无法确认是哪个上述构造函数的调用。


默认构造函数:

CPerson()

{

}

目的是使下列对象的定义形式合法:CPerson  one;

若类中定义了指定的构造函数,则隐式的默认构造函数不再存在,对于 CPerson  one 会报错。

在类的设计中,无论声明的类有几个重载的构造函数,最好有一个显式定义的默认构造函数。这样可以保证一个         类总会有一个默认的构造函数,或者是显式的,或者是隐式的。


(3)析构函数

形如:

~CPerson()

{

}

1、每个类最多有一个析构函数,且应为 public 型,否则类实例化后无法自动调用析构函数进行释放。

2、不能被重载、没有任何参数、没有返回值、函数名前不能有任何关键字。例如void

3、析构函数也可以在类体外定义,但必须指明它所属的类,在类体中还必须有析构函数的声明。

4、如果类的声明中没有定义析构函数,编译时会自动生成一个隐式的不进行任何操作的默认析构函数。


在析构函数中,当要释放的指针指向动态内存时,一定要先判断指针的指向是否有效,且内存释放后,一定要将指针置为0,NULL或null。这样当析构函数多次调用时,由于有判断语句,就不出现 ”释放未知内存的误“发生。



实验三 构造函数与析构函数 实验目的和要求 熟悉类的定义格式和类中成员的访问权限。 构造函数与析构函数的调用时机与顺序。 掌握对象的定义以及对象的初始化的时机与方法。 实验内容 1. 下面程序sy3_1.cpp中用ERROR标明的语句有错,在不删除和增加代码行的情况下,改正错误语句,使其正确运行。 //sy_1.cpp #include<iostream> using namespac... 阅读详情

相关推荐

实验 3 构造函数与析构函数

一、实验目的和要求1、熟悉类的定义格式和类中成员的访问权限。2、构造函数与析构函数的调用时机与顺序。3、掌握对象的定义以及对象的初始化的时机与方法。二、实验内容1、下面程序sy3_1.cpp中用ERROR表明的语句有错,在不删除和增加代码行的情况下,改正错误语句,使其正确运行。//sy3_1.cpp #include<iostream> using namespace std; cla...

zhangnian_666的博客 2926

C++学习摘要之二:构造函数和析构函数

构造函数和析构函数是类的两个特殊的成员函数  1.构造函数  构造函数(constructor)是类的一个特殊的成员函数,它与类名同名。当定义该类的对象时,构造函数将被系统自动调用用以实现对该对象的初始化。  构造函数不能有返回值,因而不能指定包括void在内的任何返回值类型。  构造函数的定义与其他成员函数的定义一样可以放在类内或类外。  构造函数的定义格式为:  类名(

yongzi123的专栏 996

类的构造函数与析构函数

介绍C++中的构造函数与析构函数

m0_37772174的博客 998

类的构造函数和析构函数

一、构造函数 1.1 概念 class Date { public: void SetDate(int year, int month, int day) { _year = year; _month = month; _day = day; } void Display() { cout << _year << "-" << _month...

weixin_43867777的博客 2103

ESP-01S获取网络时间踩坑全记录:AT指令调试、JSON解析乱码、时区处理,一个都不能少

本文详细记录了使用ESP-01S WIFI模块获取网络时间的完整过程,包括AT指令调试、JSON解析乱码处理以及时区转换等关键步骤。通过实战案例和代码示例,帮助开发者避开常见陷阱,实现稳定的网络时间同步功能。

weixin_30460489的博客 295

【Telephony】Telephony总纲!Phone进程流程(AOSP)

整个Framework层的Telephony框架运行在一个叫做Phone(com.android.phone)的进程中。 Phone进程启动的过程中,会初始化非常多的分支功能,SIM卡流程初始化就是其中之一,所以我觉得有必要写一下Phone进程的框架

weixin_44513784的博客 1975

Java的函数和构造函数

何为函数? 可以从另一个地方调用这个函数来实现一些计算 当一个函数被调用时,程序就转到这个函数中去运行,函数体里的语句就一条一条地被调用。一旦函数运行结束,就又回到调用它的地方去继续运行。 Java的函数必须定义在类的内部 成为类的成员 例子: <返回类型> <方法名称>(<参数表>) { <方法体> } public static void...

"✧treasure mountain✧" 8059

自制电吉他效果器 DIY PCB(二)电路图分析

自制DIY电吉他效果器 PCB(二)电路图分析 要自制一款效果器,看懂电路图是必须的,即使你已经有了完整的设计电路图,在电路的绘制已久焊接的时候电路知识都会用到。 在效果器电路中,比较简单的是过载失真类效果器的电路。混响延迟等与声相有关的由于电路比较复杂本人也没有尝试过。其他的例如EQ、哇音等等效果器复杂程度依设计各不相同,在能做出过载失真类效果器后,可以自行尝试。 我这里主要为大家介绍失真效果器...

qq_41342525的博客 2万+

构造函数是protected类型,有何用意?

1、不允许派生类以外的代码构造类对象     2、允许派生类构造类对象(一般是通过派生类的构造函数隐含调用的  使用protected还有一层意思是允许这类类成为基类,这一点和private的构造函数不同

dadalan的专栏 4222

【PCIe】CDNS PCIe VIP 杂记 -- Callback

最近在研究Cadence PCIe VIP,怎一个“惨淡”来描述。用的真是一言难尽啊,都是泪。记录一些最近学习的觉得想记录的内容在此,仅供参考讨论学习哈。有不对之处请指出大家一起讨论。

小邦是名小ICer的博客 2716

用SimaPro做碳足迹分析:手把手教你完成产品生命周期评估报告

本文详细介绍了如何使用SimaPro进行碳足迹分析,从软件安装到生命周期评估报告的完整流程。通过实战案例演示,帮助制造业企业、咨询机构和科研团队掌握产品生命周期评估(LCA)的核心技术,精准识别环境热点并优化决策,为可持续发展转型提供科学依据。

yhn45678901的博客 711

【C++】构造函数与析构函数

这篇笔记主要讲解:构造函数、构造函数的隐式调用 、析构函数。深入浅出,对两个函数的细节进行探究和总结。

Bucai_不才的博客 2192

HDR 成像技术学习(三)—— LOFIC

LOFIC(Lateral Overflow Integration Capacitor,横向溢出集合电容)介绍,从像素结构到工作时序。

沧海一升的博客 9729

浅谈构造函数与析构函数的调用顺序

构造函数      先看看构造函数的调用顺序规则,只要我们在平时编程的时候遵守这种约定,任何关于构造函数的调用问题都能解决;构造函数的调用顺序总是如下: 1.基类构造函数。如果有多个基类,则构造函数的调用顺序是某类在类派生表中出现的顺序,而不是它们在成员初始化表中的顺序。 2.成员类对象构造函数。如果有多个成员类对象则构造函数的调用顺序是对象在类中被声明的顺序,而不是它们出现在成员初始化表

永久指针 2万+

PCB Layout工程师核心能力与实战进阶指南

PCB Layout是电子硬件从原理图到物理实现的关键环节,本质是将电路逻辑转化为受电磁场、热力学与制造工艺约束的三维空间结构。其设计质量直接决定信号完整性(SI)、电源完整性(PI)和电磁兼容性(EMC)等核心性能指标。随着高速接口(如PCIe Gen5、USB3.2)、高密度封装(BGA微间距、HDI)及车规/工业级可靠性要求提升,Layout已从‘连线’演进为多目标协同优化的系统工程。掌握Altium Designer等EDA工具、理解叠层设计与DFM规则、具备SI/PI仿真意识,并能贯通芯片Data

weixin_42589700的博客 86

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C++:类的构造函数与析构函数

构造函数与析构函数

小青菜的博客 3793

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【C#】构造函数与析构函数

类的构造函数是类的一个特殊的成员函数,。默认的构造函数是没有任何参数的,可以重新设置无参数的构造函数,也可以为构造函数设置参数,构造函数的名称必须跟类名一样。1.默认使用构造函数。2.定义多个不同形参的构造函数。

Wilhelm的博客 4690

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【C++】构造函数与析构函数的使用与区别

【C++】构造函数与析构函数的使用与区别

wangnaisheng的专栏 1367

析构函数与构造函数的区别

构造函数: 什么是构造函数?通俗的讲,在类中,函数名和类名相同的函数称为构造函数。它的作用是在建立一个对象时,作某些初始化的工作(例如对数据赋予初值)。C++允许同名函数,也就允许在一个类中有多个构造函数。如果一个都没有,编译器将为该类产生一个默认的构造函数。 构造函数上惟一的语法限制是它不能指定返回类型,甚至void 也不行。 不带参数的构造函数:一般形式为 类名 对象名(){函数体} 带参数的...

qq_38769551的博客 4706
上一篇: C++内存管理
下一篇: C++中的new和delete在类中的应用
tkp2014
博客等级 码龄12年 137粉丝 241原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值