C++学习笔记(二)——构造函数和析构函数
C++学习笔记(二)——构造函数和析构函数
我的博客:竹山听雨
文章目录
- C++学习笔记(二)——构造函数和析构函数
- 构造函数
- 缺省构造函数(默认构造对象)
- 创建对象数组
- 拷贝构造函数(复制构造函数)
- 方法1
- 方法2
- 方法3
- 方法4
- 深拷贝构造函数和浅拷贝构造函数
- 构造函数对数据成员的初始化
- 在构造函数的函数体中进行初始化
- 使用构造初始化表对数据成员进行初始化
- 类类型和基本数据类型的转换
- 构造函数用作类型转换
- 类类型转换函数
- 析构函数
- 析构函数的手工调用
- 析构函数与构造函数的调用顺序
当建立一个对象时,对象的状态(数据成员的取值)是不确定的。构造函数是C++中一个特殊的成员函数,它可自动进行对象的初始化。而析构函数在对象撤销时执行清理任务,进行善后处理
特性
没有返回值说明,也就是定义构造函数和析构函数不能指出函数返回值得类型,void也不能有
它们不能被继承
构造函数可以有缺省常熟
析构函数可以是虚的,单构造函数不可以是虚的
不可取他们的地址
不能用常规调用方法调用析构函数,当使用完全的限定名(带对象名。类名和函数名)时,可以调用析构函数
当定义对象时,编译程序自动调用构造函数,当删除对象时,编译程序自动地调用析构函数
构造函数
对象的初始化是指对象数据成员的初始化,在使用对象前,一定要初始化,但因为数据成员一般为私有的(private),所以不能直接赋值。
一种方法是类中提供一个普通成员函数来初始化,但是可能会造成使用不便(使用对象前必须显式调用该函数)和不安全(未调用初始化函数就使用)
另一种方法就是使用了构造函数对对象进行初始化。
定义: 构造函数是一个与类同名,没有返回值的特殊成员函数。构造函数既可在类外定义,也可以作为内联函数在类内定义。
使用: 在定义该类对象时,可以将参数传递给构造函数来初始化对象。一般用于初始化类的数据成员,每当创建一个对象时(包括用new动态创建),会自动调用构造函数
声明: <类名>::构造函数
//类内定义
class Student{public:Student(int id,string name){...}...
}
//类外定义
class Student{public:Student();...
}
Student::Student(int id,string name){...}
//调用:
int main()
{Student s1(2,"bamboosir920");return 0;
}
注意: 构造函数也可以进行重载,构造函数也可以使用缺省参数
缺省构造函数(默认构造对象)
功能: 缺省构造参数是个无参构造函数,它仅负责创建对象,而不做任何初始化
背景: C++规定,每个类必须有一个构造函数,没有构造函数,就不能创建任何对象。若用户未显式定义一个类的构造函数,则提供给一个缺省的构造函数
eg:
class test{public:test();test(int n);
}
test::test()
{cout<<"xxx";
}
test::test()
{cout<<"xxx"
}
int main()
{test x;//调用无参数的构造函数test y(2);//调用带两个参数的构造函数
}
创建对象数组
test stu[5]={test(2),test(3),test(4),test(5),test(1)}
拷贝构造函数(复制构造函数)
功能: 是用一个已有的对象来初始化一个被创建的同类对象,是一种特殊的构造函数,具有一般构造函数的所有特性
特点: 其形参是本类对象的引用
声明:类名(类名& 对象名)
class Student{public:Student();Student(Student &);//拷贝构造函数的声明private:int id;String name;double score;...
}
Student::Student(Student &other)
{id=other.id;name=other.name;score=other.score;
}
以下四种情况会自动调用拷贝构造函数
方法1
Student s1;
Student s2(S1);
方法2
用类的一个对象去初始化另一个对象的
Student s2=s1;
方法3
对象作为函数参数传递时,调用拷贝构造函数
void f(Student a){} //定义f函数,形参为Student类对象
Student b;
f(b);
方法4
Student f() //定义f函数,返回值为Student类对象
{Student a;...return a;
}
Student b;
b=f();
深拷贝构造函数和浅拷贝构造函数
区别:
- 浅拷贝,即只复制对象空间,不复制对象资源
- 深拷贝,既复制对象空间,又复制资源
默认提供的构函数只是对对象进行浅拷贝
一般情况下,只需要使用系统提供的浅拷贝构造函数即可,但是如果对象的数据成员包括指向堆空间的指针,就不能使用这种拷贝方式,因为两个对象都拥有一个同一个资源,因此必须自定义构造函数
条件:
- 肯定要调用拷贝构造函数
- 数据成员包括指向堆内存的指针
class test{public:test(char *na) //构造函数{name=new char[strlen(na)+1];if(name!=0){strcpy(name,na);}...}test(test& p) //深拷贝构造函数{name=new char[strlen(p.name)+1]; //复制资源if(name!=0){strcpy(name,p.name); //复制对象资源}}~test(){delete name;} //析构函数private:char* name;
}
int main()
{test a("su");test li(a);return 0;
}
当在main()
中调用了深构造函数,如果却没有定义深构造函数,就会默认调用缺省的浅拷贝构造函数,就会发生报错
当数据成员有使用new
动态分配内存空间,在析构函数中使用delete
进行动态内存空间的释放以及赋值=运算符进行重载,应该自定义深拷贝构造函数
构造函数对数据成员的初始化
构造函数可以采用以下几种不同的形式对数据成员进行初始化
在构造函数的函数体中进行初始化
void test(int sid,string sname)
{id=sid;name=sname;
}
使用构造初始化表对数据成员进行初始化
<类名> ::<构造函数>(<参数表>):<变量1>(<初值1),....<变量n>(<初值n>)
{…}
注意:
- 数据成员初始化的持续取决于他们在类定义中的声明次序,与他们在成员初始化表中的次序无关
- 常量和引用的初始化必须放在构造函数正在建数据成员结构的时候,也就是放在构造函数的冒号后面
class test
{public:test(int sid,string sname):id(sid),name(sname){}private:int id;string name;
}
类类型和基本数据类型的转换
构造函数用作类型转换
前提: 此类一定是只带一个参数的构造函数
class A
{public:A();A(int);
}
类类型转换函数
在函数体中声明
operator type();
type为要转换的基本类型名,既没有参数也没有返回类型,但是在函数体重必须具有一个type类型的对象
定义转换函数的函数体
类名::opertor type()
{...return type 类型的值
}
使用类型转换函数
析构函数
功能: 当对象被撤销时,释放该对象占用的空间
作用: 当对象消亡时,系统将自动调用析构函数,执行一些在对象撤销前必须执行的清理任务
特点:
- 不能有任何的返回类型,也不能使用void
- 析构函数没有参数,每个类只能有一个析构函数
- 析构函数的函数名为
~类名
- 析构函数即可以系统自动调用也可以手工调用
自动调用的三种情况:
一个动态分配的对象被删除,即使用delete删除对象时,编译系统会自动调用析构函数
程序运行结束时
一个编译器生成的临时对象不再需要时
析构函数的手工调用
对象名.类名::析构函数名
析构函数与构造函数的调用顺序
先构造后析构
class A
{public:A(){..}A(A & S){...} //拷贝构造函数~A(){cout<<<"删除";}...
}
int main(){A X();A y(x); //拷贝构造return 0;//函数运行结束,先析构x,再析构y
}
C++学习笔记(二)——构造函数和析构函数相关推荐
- qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)
原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...
- [转载]dorado学习笔记(二)
原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...
- PyTorch学习笔记(二)——回归
PyTorch学习笔记(二)--回归 本文主要是用PyTorch来实现一个简单的回归任务. 编辑器:spyder 1.引入相应的包及生成伪数据 import torch import torch.nn ...
- tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数
tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报 分类: tensorflow(4) 目录(?)[+] 本笔记目的 ...
- Scapy学习笔记二
Scapy学习笔记二 Scapy Sniffer的用法: http://blog.csdn.net/qwertyupoiuytr/article/details/54670489 Scapy Snif ...
- Ethernet/IP 学习笔记二
Ethernet/IP 学习笔记二 原文链接:http://wiki.mbalib.com/wiki/Ethernet/IP 1.通信模式 不同于源/目的通信模式,EtherNet/IP 采用生产/消 ...
- Java学习笔记二:数据类型
Java学习笔记二:数据类型 1. 整型:没有小数部分,允许为负数,Java整型分4种:int short long byte 1.1 Int最为常用,一个Int类型变量在内存中占用4个字节,取值范围 ...
- 吴恩达《机器学习》学习笔记二——单变量线性回归
吴恩达<机器学习>学习笔记二--单变量线性回归 一. 模型描述 二. 代价函数 1.代价函数和目标函数的引出 2.代价函数的理解(单变量) 3.代价函数的理解(两个参数) 三. 梯度下降- ...
- ASP.NET MVC 2 学习笔记二: 表单的灵活提交
ASP.NET MVC 2 学习笔记二: 表单的灵活提交 前面说到有做到公司内部的一个请假系统,用的是ASP.NET MVC 2+Entity Framework.虽然EF(Entity Frame ...
- amazeui学习笔记二(进阶开发4)--JavaScript规范Rules
amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...
最新文章
- pandas -表的横向合并 纵向合并
- android 图标自动更新,android手机安装软件后会生成图标,但今后更新该软件图标都不会变化,如何使图标变成最新版的图标?...
- asp.net core mvc中如何把二级域名绑定到特定的控制器上
- 【Flink】Flink 使用 ParameterTool 进行传参
- 问题四十六:怎么用ray tracing画superellipsoid
- 防火墙配置文件iptables详解
- Mac小知识——MAC电脑如何查看IP
- apulSoft apUnmask for mac(音频放大组件)
- Apache Jackrabbit Oak 1.12.0 发布,可扩展、高性能分层存储库
- P2835 刻录光盘
- 评国内三大B2C网站首页的信息架构
- 步步高告诉你如何获客增长:4种数字化驱动案例
- 传奇高手的一天(笑话)
- excel 隔行插入和错位
- G-sensor工作原理
- MATLAB曲线绘制
- eclipse-查看继承层次图/继承实现层次图
- 人力hr管理软件的主要模块有哪些?
- Spring事务隔离级别与数据库隔离级别不一致时,该以谁为准?
- javax.servlet.http.HttpServletRequest错误
热门文章
- oracle日期时间
- 要开始Ubuntu之旅拉~
- 安装金蝶K3 提示:“安装包配置文件(setup.lst)文件不存在”
- 百度地图坐标系统应用
- springboot实现数据库数据导出到Excel中并下载到浏览器本地
- js排序的时间复杂度_js 排序算法之快速排序
- 获取别人_职场潜规则:要想获取别人信任与更多机会,先要学会勇于承担责任...
- Linux 堆分析,堆排序的分析及实现
- 网络管理软件免费linux,最新Xmanager Power Suite6网络管理工具免费官方下载6.0.199 - 系统之家...
- http请求转为https请求 java_如何将Javaweb工程的访问协议由http改为https及通过域名访问?...