(说实话,我一开始真没觉得构造函数这块有多重要,但是看的视频中老师却花了不少的时间去讲这块内容,本着整理了不亏的心态还是整理了一下)

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++之类的构造函数的更多相关文章

  1. [javase学习笔记]-7.5 构造函数须要注意的几个细节

    这一节我们简单的说几个在使用构造函数时须要注意的细节. 通过我们前几节的学习,我们对构造函数有了一个比較清楚的认识,当我们在创建对象时.我们会调用构造函数.那么我们在定义和调用构造函数时.须要注意哪些 ...

  2. 再次学习C++类之构造函数

    学习C++类,首先要说C中的结构体,虽然C++类扩展了C中的结构体,可以添加成员函数,但他们是有区别的.在结构体中,成员变量.成员函数都是公有的,而类中,一般是成员变量是私有的,成员函数是公有的,私有 ...

  3. [javase学习笔记]-7.2 构造函数与一般函数的差别

    这一节我们简单学习一下构造函数与一般函数之间的差别所在. 那么它们有什么差别呢,结合上一节,我们能够总结出下面两点差别: 第一个差别: 构造函数:对象创建时,就会调用与之相应的构造函数,对对象进行初始 ...

  4. javascript 面向对象学习(一)——构造函数

    最近在学习设计模式,找了很多资料也没有看懂,看到怀疑智商,怀疑人生,思来想去还是把锅甩到基础不够扎实上.虽然原型继承.闭包.构造函数也都有学习过,但理解得不够透彻,影响到后续提高.这次重新开始学习,一 ...

  5. C++学习基础十——子类构造函数与析构函数的执行

    1.子类构造函数的执行: 先执行父类的构造函数,再执行成员对象的构造函数,最后执行自身的构造函数. 当继承多个类时,构造函数的 执行顺序与继承时的顺序 相同,而与子类构造函数调用父类构造函数的顺序无关 ...

  6. C++学习基础六——复制构造函数和赋值操作符

    1.什么是复制构造函数 复制构造函数:是构造函数,其只有一个参数,参数类型是所属类的类型,且参数是一个const引用. 作用:将本类的成员变量赋值为引用形参的成员变量. 2.什么是赋值操作符 赋值操作 ...

  7. java学习面向对象之父子构造函数初始化

    在之前讲到java面向对象继承的时候,我们只讲到了两个比较重要的知识点,一个是父子类当中有同名的成员变量,这个时候,我们引入了super这个关键字来区分这两个同名成员变量,除此之外,我们还讲到了父子同 ...

  8. Java学习个人备忘录之构造函数&this

    构造函数 概念:构建创造对象时调用的函数. 作用:可以给对象进行初始化,创建对象都必须要通过构造函数初始化. 一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数.如果在类中定义了指 ...

  9. 我在B站学习 清华大学教授带你学习c++(进阶)构造函数

    B站av11459203的一系列视频,跳过了基础篇直接进入进阶,从此难度开始加大.这里做出一些笔记分享一下. 我是1.25速度看的..对应分P 37-38 构造函数的作用 将对象初始化为一个特定的初始 ...

随机推荐

  1. ASP.NET MVC2未能加载类型“System.Web.Mvc.ViewPage的解決方法

    问题描述: “/”应用程序中的服务器错误. 分析器错误 说明: 在分析向此请求提供服务所需资源时出错.请检查下列特定分析错误详细信息并适当地修改源文件. 分析器错误消息: 未能加载类型“System. ...

  2. vue源码分析—Vue.js 源码构建

    Vue.js 源码是基于 Rollup 构建的,它的构建相关配置都在 scripts 目录下.(Rollup 中文网和英文网) 构建脚本 通常一个基于 NPM 托管的项目都会有一个 package.j ...

  3. CentOS7.x编译安装zabbix4.0

    编译安装zabbix Zabbix简介 Zabbix 是一个企业级的分布式开源监控方案. Zabbix是一款能够监控各种网络参数以及服务器健康性和完整性的软件.Zabbix使用灵活的通知机制,允许用户 ...

  4. 随心测试_软测基础_005 <测试人员工作内容>

    接上篇:清楚了_测试人员的工作职责范围,那每项 测试活动的具体工作内容有哪些呢? Q1:如何理解测试工程师的工作内容? A1:SX的观点:综合一体化 现如今互联网行业如何哪达,每一项IT职业的工作职责 ...

  5. python官网几个下载文件的区别

    进入python官方,下载python编译器,提供了如下几个版本进行选择,这些版本分别是什么意思呢? Python 3.7.1 - 2018-10-20 Download Windows x86 we ...

  6. “理了么”软件特点NABCD个人分析

    在这里我就主要对此软件的‘A’(做法)和‘B’(好处)两方面进行分析. “A”:我们的软件为顾客和商家分别提供一种账户,分别登陆后会显示不同的界面. 1.用户界面:拥有“理发店”.“订单“.”和“我的 ...

  7. cocos 动画系统

    前面的话 cocos 动画系统支持任意组件属性和用户自定义属性的驱动,再加上可任意编辑的时间曲线和移动轨迹编辑功能,就可以制作出各种动态效果 概述 Animation 组件可以以动画方式驱动所在节点和 ...

  8. vue router 修改title(IOS 下动态改变title失效)

    在ios下app  设置document.title = "titleName" 失效,原因是在IOS webview中网页标题只加载一次,动态改变是无效的. 在路由配置中添加   ...

  9. Nginx+rtmp+ffmpeg 搭建推流服务器

    1. 安装nginx服务器 1.1 clone $ brew tap denji/homebrew-nginx 1.2 安装 $ brew install nginx-full --with-rtmp ...

  10. 我的python之路

    一.基础语法 Python基础—基本语法结构 Python基础—程序控制结构 Python基础—基本数据类型 Python基础—文件的读写操作 二.函数 Python基础—初识函数 Python基础— ...