【C++第六课】---析构与构析下
来源:互联网 发布:java基本类型有哪些 编辑:程序博客网 时间:2024/04/29 13:34
一、在C++中对象是如何组合的
1.问题的引入----在C++中我们如何将对象成员进行初始化
首先要明确的是你真的能够分清楚什么是赋值,什么又是初始化么?
初始化与赋值不同
初始化是用已存在的对象或值对正在创建的对象进行初值设置
赋值是用已存在的对象或值对已经存在的对象进行值设置
区别:
初始化: 被初始化的对象正在创建
赋值: 被赋值的对象已经存在
2.所以我们就能够明白一点 :构造函数体部分只是对我们的变量进行赋值 并非是我们通常所说的初始化
那么这时候我们需要思考,C++中真正意义上的初始化是怎么做的呢?
3.初始化列表的引入---初始化变量
可以说初始化列表的引入恰恰满足了我们对变量初始化的需要,下面举例说明。
example1.cpp
#include <iostream>using namespace std;class Test {private:int mI;public:Test(int i){cout<<"mI = %d"<<mI<<endl;mI = i;}int GetI(){return mI;}};class M{private:const int mJ;//定义常量,但是没有初始化!!!Test M1;//定义了一个类成员,这样做可行么?Test M2;public:M(){cout<<"M() \n"<<endl;}};int main(){M m1;return 0;}上面的例子在gcc环境下编译的时候会提示如下问题
9_1.cpp: In constructor ‘M::M()’:
9_1.cpp:27: error: uninitialized member ‘M::mJ’ with ‘const’ type ‘const int’
9_1.cpp:28: error: no matching function for call to ‘Test::Test()’
9_1.cpp:10: note: candidates are: Test::Test(int)
9_1.cpp:6: note: Test::Test(const Test&)
9_1.cpp:28: error: no matching function for call to ‘Test::Test()’
9_1.cpp:10: note: candidates are: Test::Test(int)
9_1.cpp:6: note: Test::Test(const Test&)
意思是说我们声明变量mJ,M1,M2的时候没有对它进行初始化,当然会出错的。
所以我们修改成下面的程序,用初始化列表进行初始化就行了
#include <iostream>using namespace std;class Test {private:int mI;public:Test(int i){mI = i;cout<<"mI = "<<mI<<endl;}int GetI(){return mI;}};class M{private:const int mJ;Test M1;Test M2;public:M():mJ(1),M1(2),M2(3){cout<<"M() \n"<<endl;}};int main(){M m1;return 0;}
当让值得注意的就是:1.成员变量的初始化顺序与声明的顺序相关,与在初始化列表中的顺序无关
2.初始化列表先于构造函数的函数体执行
二、所谓析构函数
C + +中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数。
定义:~ClassName()
析构函数没有参数也没有任何返回类型的声明
析构函数在对象销毁时自动被调用
注意:
构造函数与析构函数的调用秩序
1.当类中有成员变量是其它类的对象时,首先调用成员变量的构造函数调用顺序与声明顺序相同
2.后调用自身类的构造函数析构函数的调用秩序与对应的构造函数调用秩序相反
举例如下:
#include <iostream>using namespace std;class Test {private:int mI;public:Test(int i){mI = i;cout<<"Test mI = "<<mI<<endl;}~Test(){cout<<"~Test : mI = "<<mI<<endl;}};class M {private:const int mm;Test mI;Test mJ;public:M():mm(0),mI(1),mJ(2){cout<<"M() mm = "<<mm<<endl;}~M(){cout<<"~M mm = "<<mm<<endl;}};int main(){M m1;M m2;return 0;}
仔细分析会得出如下结果:
Test mI = 1Test mI = 2M() mm = 0Test mI = 1Test mI = 2M() mm = 0~M mm = 0~Test : mI = 2~Test : mI = 1~M mm = 0~Test : mI = 2~Test : mI = 1
- 【C++第六课】---析构与构析下
- C语言第六课
- C语言第六课
- 第六课、C数据类型
- 【笔记】C与指针 第六章 指针
- C语言第六课 函数
- 数据结构与算法 第六课
- C#教程第六课:名称空间
- C#教程第六课:名称空间
- 小小君的C语言第六课
- for循环-c基础第六课
- 我的c语言第六课
- 第六篇 Java编译器与C/C++编译器的比较
- 程序设计与C语言学习笔记_第六章数组
- [Coursera 计算导论与C语言基础] 第六周作业
- 《Effective C++》第六章:继承与面向对象设计
- C陷阱与缺陷第六章 预处理器
- Andriod第六课----进程与线程
- 多线程基本概念知识
- [2013.10.20]Eclipse配置Git全过程-----------附用EGit不能push的问题解决
- Udp-发送端
- project euler problem 35求一个数的所有循环数都是素数的总共有多少个
- Sequences
- 【C++第六课】---析构与构析下
- 关于fork进程的理解——Understanding about the fork process
- 括号配对问题
- 加密知识
- 网址收藏
- hdu 3333 Turing Tree 线段树
- Android事件传递机制-View篇
- 数据结构二叉树的两个题目
- Shell 相关 find cp fo