C++中的经典问题解析
来源:互联网 发布:毛星云windows 编辑:程序博客网 时间:2024/05/22 22:55
c++中的对象的构造顺序与析构顺序
今天第一次写博客,毕竟还是菜鸟,所以就只把自己的学习笔记记录一下吧,以后学有所成,一定会分享牛逼的技术博客!!!
问题一
当程序中存在多个对象时,如何确定这些对象的析构顺序?
一.单个函数创建时构造函数的调用顺序
1.调用父类的构造过程
2.调用成员变量的构造函数(调用顺序与声明顺序相同)
3.调用类自身的构造函数
而析构函数与对应构造函数的调用顺序相反!多个对象析构时析构顺序与构造顺序想反。
下面分析一段简单的代码:
#include <stdio.h>class Member{ const char* ms;public: Member(const char* s) { printf("Member(const char* s): %s\n", s); ms = s; } ~Member() { printf("~Member(): %s\n", ms); }};class Test{ Member mA; Member mB;public: Test() : mB("mB"), mA("mA") { printf("Test()\n"); } ~Test() { printf("~Test()\n"); }};Member gA("gA");int main(){ Test t; return 0;}
首先代码中没有父类,那么调用成员变量的构造函数,调用的顺序要与声明的顺序相同,看代码知先声明的是全局变量Member gA(“gA”),然后是局部变量:Member mA; Member mB,注意mA和mB这两个变量得顺序不要被 Test() : mB(“mB”), mA(“mA”)这里的定义顺序搞混了,我们的构造顺序是声明的顺序,而不是定义的顺序,那里的定义的顺序是为了给我们造成混淆的,定义的顺序可以随便改变!接着就是调用类自身的构造函数,Test(),它会执行printf(“Test()\n”);
好了,到这一步,说明构造函数调用完成。调用的顺序为:gA,mA,mB,Test().
而析构函数与构造函数的调用顺序相反,所以析构函数的调用顺序为:~Test(), mB, mA, gA.
对于栈对象和全局对象,类似于入栈与出栈的顺序,最后构的对象被最先析构!!
堆对象的析构发生在使用delete的时候,与delete的使用顺序相关!!
问题二
const 关键字能否修饰类的对象?如果能,有什么特性?
我们知道,在c++中,const可以修饰一个只读变量,也可以修饰一个真正意义上的常量。那么它能否修饰类的对象呢?我们知道类只不过是由struct演变而来的一种用户自定义的数据类型,从某种意义上来讲,它也是一个变量,既然是变量,那么能不能用const修饰它呢?
答案是肯定的!
1.const关键字能够修饰对象
2.const修饰的对象为只读对象
3.只读对象的成员变量不允许被改变
3.只读对象是编译阶段的概念,运行时无效
下面介绍一下C++中const成员函数的定义:
Type ClassName::function(Type p) const
类中的函数声明与实际的函数定义都必须带有const关键字。文字太多不如直接上代码(代码太简单大佬们不要嘲笑,毕竟小弟很菜!!!):
#include <stdio.h>class Test{ int mi;public: Test(int i); Test(const Test& t); int getMi();};Test::Test(int i){ mi = i;}Test::Test(const Test& t){ mi = t.getMi(); //能否编译通过?}int Test::getMi(){ return mi;}int main(){ const Test t(1); t.mi = 100; //能否编译通过? printf("t.getMi() = %d\n",t.getMi()); //能否编译通过?如何才能编译通过? return 0;}
我把程序放到linux中进行编译,很显然编译不通过,显示的错误有哪些呢?
test.cpp: In copy constructor ‘Test::Test(const Test&)’:
test.cpp:19: error: passing ‘const Test’ as ‘this’ argument of ‘int Test::getMi()’ discards qualifiers
test.cpp: In function ‘int main()’:
test.cpp:5: error: ‘int Test::mi’ is private
test.cpp:31: error: within this context
test.cpp:31: error: assignment of data-member ‘Test::mi’ in read-only structure
test.cpp:33: error: passing ‘const Test’ as ‘this’ argument of ‘int Test::getMi()’ discards qualifiers
首先mi = t.getMi();
无法编译通过,因为Test::Test(const Test& t)中的的参数为const的引用,const成员函数只能调用const成员函数。
然后t.mi = 100;
编译不通过,因为int Test::mi’ is private,并且‘Test::mi’ in read-only structure,因为我们定义的是const成员函数const Test t(1);这才是我们想说的真正原因。
其次printf("t.getMi() = %d\n",t.getMi());
编译不通过 ,因为成员t在上面被定义的是const类型。 那么,该如何让它编译通过呢?在int getMi();
函数后面加上const变为
int getMi()const;
在int Test::getMi()
后面加上const变为
`int Test::getMi()const`
那么这条语句 printf("t.getMi() = %d\n",t.getMi());
就可以编译通过了!!!
此时如果在函数int Test::getMi()
中加入 mi = 2;
则编译又不会通过了,因为该函数已经被定义为const类型,不能改写成员变量的值了!!!
由以上代码的实际试验得出具体结论如下:
C++中const成员函数的特性:
-const const对象只能调用const成员函数;
-const 成员函数中只能调用const成员函数;
-const 成员函数中不能直接改写成员变量的值。
- C++中的经典问题解析
- C语言中的经典问题之数组
- c语言经典解析
- C语言中的越界问题解析
- 经典问题解析三
- C++经典问题解析
- C经典 内存分配解析
- 操作系统中的经典问题
- C,C++经典问题
- c解决经典问题
- 经典问题解析(二)
- Android AsyncTask经典问题解析
- 经典问题解析(4)
- 67-经典问题解析五
- 经典问题解析(1)---const和引用、指针与引用、函数重载、C方式编译
- php面试中的经典问题
- SQL中的两个经典问题
- 博弈论中的几个经典问题
- Web前段开发中The requested resource is not available的解决办法
- 第四次上机作业
- CF886E Maximum Element
- spring 启动过程分析(二)
- hibernate查询方式
- C++中的经典问题解析
- Android Studio 3.0 清除项目用不到的资源
- 流水账
- Python,字典
- 数据结构Note1:Hash 表(散列表/哈希表)
- 12.2日笔记
- 浅谈函数的调用过程,栈帧的创建和销毁
- pat 乙级 1015. 德才论 (25) c++
- 初始MQTT协议(3)