【7】学习C++之类的构造函数
(说实话,我一开始真没觉得构造函数这块有多重要,但是看的视频中老师却花了不少的时间去讲这块内容,本着整理了不亏的心态还是整理了一下)
1.常见的构造函数
C++的类在创建对象的时候,都会去调用构造函数,这种行为是强制的。如果在类中没去写构造函数,程序会自动为你的类创建出构造函数,然后去调用他(这个构造函数的函数体是空的,也没有形参,也不执行任何操作。);如果你已经写了构造函数,那么程序在运行的时候会去调用你写的构造函数。
构造函数是可以被重载的,一个类可以有多个重载的构造函数,创建对象时根据传递的实参来判断调用哪一个构造函数。
构造函数中又细分出默认构造函数,具体区别有三言两语不好去说明,还是直接上图比较好:

(感觉这块知识点除了学生在期末考试会考到,其他地方真能用到么)
如果看了上图还不能理解,只能放代码了
class Student
{
public:
//Student(){}//无参构造函数,默认构造函数
Student():m_strName("Jim"),m_iAge(){}//无参构造函数,默认构造函数
/*Student(string _strName,int _iAge)//无参构造函数,参数不带默认值,不是默认构造函数
{
m_strName=_strName;
m_iAge=_iAge;
}*/
Student(string _strName,int _iAge):m_strName("Jim"),m_iAge()//无参构造函数,参数带默认值,是默认构造函数
{
m_strName=_strName;
m_iAge=_iAge;
}
private:
string m_strName;
int m_iAge;
}
2.拷贝构造函数
定义格式:类名(const 类名& 变量名)
要点1:如果没有自定义的拷贝构造函数,系统会自动生成一个默认的拷贝构造函数。
要点2:当采用直接初始化或复制初始化实例化对象时系统会自动调用拷贝构造函数。
要点3:拷贝构造函数不能被重载。
要点4:拷贝构造函数在参数传递的时候也会被调用。
老惯例,上代码
class abc
{
public:
abc(){};
abc(const abc &aaa){}
private:
int a;
}
void text(abc aa3)
{ }
int main()
{
abc aa;
abc aa1 = aa;//调用拷贝构造函数
abc aa2(aa);//调用拷贝构造函数
text(aa);//调用拷贝构造函数 return ;
}
3.深拷贝和浅拷贝
其中拷贝构造函数分为浅拷贝和深拷贝,继续按照惯例上代码:
#include <iostream>
using namespace std; class text
{
public:
text():t_a(),t_b(){};
text(const text &aa):t_a(aa.t_a),t_b(aa.t_b){};//浅拷贝
private:
int t_a;
int t_b;
};
int main()
{
text a;
text b = a;
return ;
}
在上面的代码中,b就是依靠拷贝的方式初始化的,就是将 a 所在内存中的数据按照二进制位(Bit)复制到 b 所在的内存,这种默认的拷贝行为就是浅拷贝。
有浅就有深,既然有了浅拷贝,那么肯定就会有深拷贝。浅拷贝有它的缺陷,在遇到动态分配的内存、指向其他数据的指针的情况时,就会出现一些BUG,甚至会导致程序的崩溃。下面上一个本该用深拷贝却用浅拷贝的错误代码:
#include <iostream>
using namespace std; class Array
{
public:
Array()
{
m_iCount = ;
m_pArr = new int[m_iCount];
};
Array(const Array &aa)
{
m_iCount = aa.m_iCount;
m_pArr = aa.m_pArr;//此处会导致错误
};
private:
int m_iCount;
int *m_pArr;
};
int main()
{
Array a;
Array b = a;
return ;
}
在上面的代码中,a的成员变量m_pArr是个指向动态分配内存的数组的第一个地址的指针,经过浅拷贝,b的成员变量m_pArr也是指向着相同地址,这会导致修改b的数组时,a的数组也会跟着发生变化,当a销毁的时候,b的指针指向的数组则不存在,等等许多问题。所以我们需要作出一些改变来应对这种情况,于是深拷贝应运而生。
按照惯例,放出修改后的代码:
class Array
{
public:
Array()
{
m_iCount = ;
m_pArr = new int[m_iCount];
};
Array(const Array &aa)
{
m_iCount = aa.m_iCount;
m_pArr = new int[m_iCount];
for (int i; i < m_iCount; i++)
{
m_pArr[i] = aa.m_pArr[i];
}
};
private:
int m_iCount;
int *m_pArr;
};
这种将对象所持有的其它资源一并拷贝的行为叫做深拷贝,我们必须显式地定义拷贝构造函数才能达到深拷贝的目的。
所以,什么时候用深拷贝什么时候用浅拷贝呢?
如果一个类拥有指针类型的成员变量,那么绝大部分情况下就需要深拷贝,因为只有这样,才能将指针指向的内容再复制出一份来,让原有对象和新生对象相互独立,彼此之间不受影响。如果类的成员变量没有指针,一般浅拷贝足以。
【7】学习C++之类的构造函数的更多相关文章
- [javase学习笔记]-7.5 构造函数须要注意的几个细节
这一节我们简单的说几个在使用构造函数时须要注意的细节. 通过我们前几节的学习,我们对构造函数有了一个比較清楚的认识,当我们在创建对象时.我们会调用构造函数.那么我们在定义和调用构造函数时.须要注意哪些 ...
- 再次学习C++类之构造函数
学习C++类,首先要说C中的结构体,虽然C++类扩展了C中的结构体,可以添加成员函数,但他们是有区别的.在结构体中,成员变量.成员函数都是公有的,而类中,一般是成员变量是私有的,成员函数是公有的,私有 ...
- [javase学习笔记]-7.2 构造函数与一般函数的差别
这一节我们简单学习一下构造函数与一般函数之间的差别所在. 那么它们有什么差别呢,结合上一节,我们能够总结出下面两点差别: 第一个差别: 构造函数:对象创建时,就会调用与之相应的构造函数,对对象进行初始 ...
- javascript 面向对象学习(一)——构造函数
最近在学习设计模式,找了很多资料也没有看懂,看到怀疑智商,怀疑人生,思来想去还是把锅甩到基础不够扎实上.虽然原型继承.闭包.构造函数也都有学习过,但理解得不够透彻,影响到后续提高.这次重新开始学习,一 ...
- C++学习基础十——子类构造函数与析构函数的执行
1.子类构造函数的执行: 先执行父类的构造函数,再执行成员对象的构造函数,最后执行自身的构造函数. 当继承多个类时,构造函数的 执行顺序与继承时的顺序 相同,而与子类构造函数调用父类构造函数的顺序无关 ...
- C++学习基础六——复制构造函数和赋值操作符
1.什么是复制构造函数 复制构造函数:是构造函数,其只有一个参数,参数类型是所属类的类型,且参数是一个const引用. 作用:将本类的成员变量赋值为引用形参的成员变量. 2.什么是赋值操作符 赋值操作 ...
- java学习面向对象之父子构造函数初始化
在之前讲到java面向对象继承的时候,我们只讲到了两个比较重要的知识点,一个是父子类当中有同名的成员变量,这个时候,我们引入了super这个关键字来区分这两个同名成员变量,除此之外,我们还讲到了父子同 ...
- Java学习个人备忘录之构造函数&this
构造函数 概念:构建创造对象时调用的函数. 作用:可以给对象进行初始化,创建对象都必须要通过构造函数初始化. 一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数.如果在类中定义了指 ...
- 我在B站学习 清华大学教授带你学习c++(进阶)构造函数
B站av11459203的一系列视频,跳过了基础篇直接进入进阶,从此难度开始加大.这里做出一些笔记分享一下. 我是1.25速度看的..对应分P 37-38 构造函数的作用 将对象初始化为一个特定的初始 ...
随机推荐
- Problem of Creating Topics in Kafka with Kerberos
Hi, After enabled Kerberos using Ambari, I got problem creating topics in Kafka using the kafka-topi ...
- 解决consul覆盖注册
默认注册consul的服务id为服务名-端口号,相同的服务名和端口号注册会覆盖 解决方式: 1.自定义Consul注册Id import com.ecwid.consul.v1.ConsulClien ...
- 机器翻译评价指标 — BLEU算法
1,概述 机器翻译中常用的自动评价指标是 $BLEU$ 算法,除了在机器翻译中的应用,在其他的 $seq2seq$ 任务中也会使用,例如对话系统. 2 $BLEU$算法详解 假定人工给出的译文为$re ...
- Codeforces round 1086
Div1 528 我菜哭了.jpg 这个C的出题人能不能停止出题啊QaQ A 这不是裸的斯坦纳树嘛! 然后我就写上了.jpg 然后我没调出来... 然后我发现...这不是傻逼题吗... 直接按照$x$ ...
- [转帖]Ansible管理windows集群
Ansible管理windows集群 http://www.cnblogs.com/Dev0ps/p/10026908.html 写的挺好的 我关注点还是不够好呢 最近公司新项目需要安装400+win ...
- 「SDOI2017」树点涂色 解题报告
「SDOI2017」树点涂色 我sb的不行了 其实一开始有一个类似动态dp的想法 每个点维护到lct树上到最浅点的颜色段数,然后维护一个\(mx_{0,1}\)也就是是否用虚儿子的最大颜色 用个set ...
- MATLAB-卡尔曼滤波简单运用示例
1.角度和弧度之间的转换公式? 设角度为 angle,弧度为 radian radian = angle * pi / 180; angle = radian * 180 / pi; 所以在matla ...
- jmeter笔记(8)--关联
关联是jmeter中比较重要的一个点,在测试过程中有些数据是经常发生变化的,要获取这些数据,就需要使用关联,Jmeter可以通过“后置处理器”中的“正则表达式提取器”来处理关联.. 正则表达式提取器 ...
- MySQL数据库、表常用操作
1.按条件查询表中数据: mysql> select user,host,password from user; 2.按组合条件查询表中数据: mysql> select id, pass ...
- Spring定时器配置与运用,及Cron表达式的详解
一:首先在spring的配置文件里配置一个定时器 <task:executor id="executor" pool-size="5" /> < ...