构造函数和析构函数是C++的重要组成部分,了解构造函数和析构函数有助于深入了解C++

构造函数

构造函数产生的原因

在C++中,有时候需要在对象创建的时候初始化数据,如果采用普通函数的话,每次初始化都要调用函数,显得麻烦,另外,如果忘记初始化,那么其结果是未知的。

在C++中使用构造函数来完成初始化,使得对象在生成的时候就完成初始化动作

构造函数定义

  1. C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数
  2. 构造函数在定义时可以有参数
  3. 没有任何返回类型的声明
class Test
{
public:
//构造函数 无参构造函数 默认构造函数
Test()
{
a = 10;
} //带参数的构造函数
Test(int mya)
{
a = mya;
} //赋值构造函数 copy构造函数
Test(const Test & obj)
{
;
}
protected:
private:
int a;
};

构造函数的调用

  1. 自动调用:一般情况下C++编译器会自动调用构造函数
  2. 手动调用:在一些情况下则需要手工调用构造函数
//无参构造函数调用,适合C++默认的构造函数
Test t0; //有参构造函数掉用:3种
Test t1(10); //自动调用
Test t2 = 11; //自动调用
Test t3 = Test(12); //手动调用 //copy构造函数调用:4种
Test t4;
//第一种:
Test t5 = t4;//定义并初始化,用t4初始化t5-->t5 = t4不同,后者属于浅拷贝
//第二种
Test t6(t4);
//第三种
//如果存在函数void func(Test p){},那么在类做函数参数的时候会调用copy构造函数
Test t7(10);
func(t7);
//第四种
//在定义返回值为类的函数时,会调用copy构造函数,此时生成一个匿名对象
Test func()
{
Test t8(10);
return t8;
}
//这个函数引出匿名对象的生命周期问题
Test t9;
t9 = func();//这种方法会有三次构造三次析构,属于浅拷贝
Test t9 = func();//这种方法直接将匿名对象转化为t9,只经历两次构造和两次析构

特殊的构造函数

  1. 无参构造函数

    当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空
  2. 拷贝构造函数

    当类中没有定义拷贝构造函数时,编译器默认提供一个拷贝构造函数,简单的进行成员变量的值复制

构造函数的规则和理解

  • 当类中没有定义任何一个构造函数时,c++编译器会提供无参构造函数和拷贝构造函数
  • 当类中定义了任意的非拷贝构造函数,c++编译器不会提供无参构造函数
  • 当类中定义了拷贝构造函数时,c++编译器不会提供无参数构造函数
  • 默认拷贝构造函数成员变量简单赋值
  • 构造函数是C++中用于初始化对象状态的特殊函数
  • 构造函数在对象创建时自动被调用
  • 构造函数和普通成员函数都遵循重载规则
  • 拷贝构造函数是对象正确初始化的重要保证
  • 必要的时候,必须手工编写拷贝构造函数

构造函数的初始化列表

产生的原因

由于在多个类中存在包含关系,导致在包含其他类的类中初始化不明确

此时会造成没有合适的默认构造函数

如果有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,没有默认构造函数。这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错

使用

Constructor::Contructor() : m1(v1), m2(v1,v2), m3(v3)
{
// some other assignment operation
}

初始化:被初始化的对象正在创建

赋值:被赋值的对象已经存在

成员变量的初始化顺序与声明的顺序相关,与在初始化列表中的顺序无关

初始化列表先于构造函数的函数体执行

#include "iostream"
using namespace std; class ABC
{
public:
ABC(int a, int b, int c)
{
this->a = a;
this->b = b;
this->c = c;
printf("a:%d,b:%d,c:%d \n", a, b, c);
printf("ABC construct ..\n");
}
~ABC()
{
printf("a:%d,b:%d,c:%d \n", a, b, c);
printf("~ABC() ..\n");
}
protected:
private:
int a;
int b;
int c;
}; class MyD
{
public:
MyD():abc1(1,2,3),abc2(4,5,6),m(100)
{
cout<<"MyD()"<<endl;
}
~MyD()
{
cout<<"~MyD()"<<endl;
} protected:
private:
ABC abc1;
ABC abc2;
const int m;
}; int run()
{
MyD myD;
return 0;
} int main()
{
run();
system("pause");
return 0;
}
#include "iostream"
using namespace std; class ABCD
{
public:
ABCD(int a, int b, int c)
{
this->a = a;
this->b = b;
this->c = c;
printf("ABCD() construct, a:%d,b:%d,c:%d \n", this->a, this->b, this->c);
}
~ABCD()
{
printf("~ABCD() construct,a:%d,b:%d,c:%d \n", this->a, this->b, this->c);
}
int getA()
{
return this->a;
}
protected:
private:
int a;
int b;
int c;
}; class MyE
{
public:
MyE():abcd1(1,2,3),abcd2(4,5,6),m(100)
{
cout<<"MyD()"<<endl;
}
~MyE()
{
cout<<"~MyD()"<<endl;
}
MyE(const MyE & obj):abcd1(7,8,9),abcd2(10,11,12),m(100)
{
printf("MyD(const MyD & obj)\n");
} protected:
//private:
public:
ABCD abcd1;
ABCD abcd2;
const int m; }; int doThing(MyE mye1)
{
printf("doThing() mye1.abc1.a:%d \n", mye1.abcd1.getA());
return 0;
} int run()
{
MyE myE;
doThing(myE);
return 0;
} int main()
{
run();
system("pause");
return 0;
}

析构函数

析构函数产生的原因

构造函数在对象被创建时候调用,而析构函数则相反,是在对象被销毁时候调用,用于清理内存或者变量

C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数

析构函数定义

~ClassName()
  1. 析构函数没有参数也没有任何返回类型的声明
  2. 析构函数在对象销毁时自动被调用
  3. 析构函数调用机制:C++编译器自动调用

总结

当类中有成员变量是其它类的对象时

首先调用成员变量的构造函数

调用顺序与声明顺序相同

之后调用自身类的构造函数

析构函数的调用秩序与对应的构造函数调用秩序相反

class Test
{
public:
Test()
{
cout<<"构造函数自动被调用"<<endl;
} ~Test()
{
cout<<"析构函数自动被调用"<<endl;
}
protected:
private:
};
···

C++学习笔记-构造函数和析构函数的更多相关文章

  1. 学习C++ -> 构造函数与析构函数

    学习C++ -> 构造函数与析构函数 一.构造函数的介绍    1. 构造函数的作用        构造函数主要用来在创建对象时完成对对象属性的一些初始化等操作, 当创建对象时, 对象会自动调用 ...

  2. C++学习之构造函数和析构函数及指针

    C++的构造函数在创建对象时调用,分配内存空间,多少个对象(对象数组)就调用几次构造函数:析构函数在调用结束时调用(可以添加一些最后的处理)以释放内存给其它来用.对于同类型同生命期的对象,先创建的对象 ...

  3. 鸡啄米:C++编程之十四学习之构造函数和析构函数

    1. 本人学习鸡啄米课程的笔记记录,用来记录学习的历程和进度 2. 构造函数 我们在声明一个变量时,如果对它进行了初始化,那么在为此变量分配内存空间时还会向内存单元中写入变量的初始化.声明对象有相似的 ...

  4. C++笔记----构造函数与析构函数(二)

    构造函数是一种特殊的成员函数.在创建对象的时候自动调用,对对象的数据成员进行初始化. (1)栈区中创建的对象,在生存期结束的时候会自动调用析构函数. (2) 在堆上创建的对象,要由程序员显示调用del ...

  5. C++笔记----构造函数与析构函数(三)

    1.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段:初始化段. 普通计算段 2.对象成员及其初始化 #include<iostream> using ...

  6. c++学习笔记——构造函数

    构造函数定义:每个类都分别定义了它的对象被初始化的方式,类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数. 需要注意的几点: 1:构造函数不能被声明为const的,当我们创 ...

  7. JavaScript学习笔记-构造函数

    什么是构造函数 简单说构造函数是类函数,函数名与类名完全相同,且无返回值.构造函数是类的一个特殊成员函数. JavaScript构造函数 * 在JavaScript的世界里没有类的概念,JavaScr ...

  8. JS学习笔记-构造函数篇

    创建实例 funtion Fn (){     var num = 10;         this.x = 100;     this.getX = function(){         cons ...

  9. 《C++ Primer Plus》10.3 类的构造函数和析构函数 学习笔记

    10.3.1 声明和定义构造函数构造函数原型:// constructor prototype with some default argumentsStock(const string &c ...

随机推荐

  1. Python之列表与元组的区别详解

    相同点:都是序列类型 回答它们的区别之前,先来说说两者有什么相同之处.list 与 tuple 都是序列类型的容器对象,可以存放任何类型的数据.支持切片.迭代等操作 foos = [0, 1, 2, ...

  2. HGOI 20190828 题解

    Problem A 数学题 设数论函数$f(x)$表示$x(x ∉ Prime)$的次大因数, 给出$l,r$求出$\sum\limits_{i=l,i ∉ Prime} ^r f(i)$ . 对于$ ...

  3. BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树

    题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...

  4. 深度学习笔记(十四)车道线检测 SCNN

    论文:Spatial As Deep: Spatial CNN for Traffic Scene Understanding 代码:https://github.com/XingangPan/SCN ...

  5. Android UI编程之自定义控件初步——ImageButton

    我想我们在使用一些App的时候,应该不会出现一些“裸控件”的吧.除非是一些系统中的软件,那是为了保持风格的一致性,做出的一些权衡.我这里并非是在指责Android原生的控件不好看,说实在的,我很喜欢A ...

  6. AtCoder AGC032E Modulo Pairing (二分、贪心与结论)

    题目链接 https://atcoder.jp/contests/agc032/tasks/agc032_e 题解 猜结论好题. 结论是: 按\(a_i\)从小到大排序之后,一定存在一种最优解,使得以 ...

  7. simple queue(简单队列)

    Virtual host-虚拟主机 虚拟主机,用于进行逻辑隔离,是最上层的路由,类似于redis的16个db,是一种逻辑上的隔离 一个virtualhost里面可以有若干个Exchange和Queue ...

  8. 2、dubbo基础知识

    1.简介 2.dubbo架构 3.dubbo环境搭建 注意:cmd命令都是在bin目录的地址栏直接输入 xxx.cmd 4.配置dubbo-admin 步骤一: 步骤二: 步骤三: 步骤四: 步骤五: ...

  9. MERGE INTO 解决大数据量复杂操作更新慢的问题

    现我系统中有一条复杂SQL,由于业务复杂需要关联人员的工作离职三个表,并进行分支判断,再计算人员的字段信息,由于人员多,分支多,计算复杂等原因,一次执行需要5min,容易卡死,现在使用MERGE IN ...

  10. mumu 连接安卓studio

    近期开发一个项目,折腾了好久,编写完程序后,真机上运行没有异常,而在MuMu模拟器上运行,程序总是中断(MuMu模拟器连接不上,只能打包好apk再放到MuMu上测试,有点蠢萌...),没办法调试,就获 ...