C++中的析构顺序和cosnt对象
1,当程序中存在多个对象的时候,如何确定这些对象的析构顺序?
2,单个对象创建时构造函数的调用顺序(工程经验总结):
1,调用父类的构造过程;
2,调用成员变量的构造函数(调用顺序与声明顺序相同);
1,某个类的成员是其它类的对象;
3,调用类自身的构造函数;
1,析构函数与对应构造函数的调用顺序相反;
3,多个对象析构时:
1,构造顺序与析构顺序相反;
4,构造与析构顺序实例分析:
#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; // gA
// mA
// mB
// Test()
// ...
//~Test()
// mB
// mA
// gA return ;
}
5,对于栈对象和全局对象,类似于入栈与出栈的顺序,最后构造的对象最先析构;堆对象的析构发生在使用 delete 的时候,与 delete 的顺序相关;
6,const 关键字能否修饰类的对象?如果可以,有什么特性?
1,const 关键字能够修饰对象;
1,类也是用户自定义的数据类型,类是从 struct 进化而得到的一个全新关键字,struct 专门用来定义结构体,其定义的结构体在 C 语言中依旧是变量,既然是变量,就可以被 cosnt 所修饰;
2,对应的,对象在某种角度也是变量,所以也可以被 const 修饰;
2,const 修饰的对象为只读对象;
1,这是唯一的可能性;
3,只读对象的成员变量不允许被改变;
1,对象就是由一系列的成员变量构成的,对象已经是只读的了,也就意味着成员变量是不允许被改变的;
4,只读对象是编译阶段的概念,运行时无效;
1,只读对象起始还是可以被改变的;
7,C++ 中的 const 成员函数:
1,const 对象只能调用 const 的员函数;
1,因为 const 对象的 this 指针是底层常量,不能拷贝给非 const 的成员函数的 this 指针,因为后者的 this 是变量,这会改变 const *this 的属性,造成其指向的对象会被改变;
2,const 成员函数中只能调用 const 成员函数;
1,底层 const 指针不能拷贝给非 const 指针;
3,const 成员函数中不能直接改写成员变量的值;
1,const 成员函数只能被 const 对象调用,而此时其成员函数也底层 const 的,不能修改底层 const 指针指向的变量;
4,const 成员函数特殊的意义是被只读对象调用;
1,底层 const 指针不能拷贝给非 const 指针;
8,const 成员函数的定义:
1,Type ClassName::function(Type p) const
1,声明之后,函数体之前;
2,类中的函数声明与实际函数定义中都必须带 const 关键字;
9,类的 const 函数初探编程实验:
#include <stdio.h> class Test
{
int mi;
public:
int mj; Test(int i);
Test(const Test& t);
int getMi() const;
}; Test::Test(int i)
{
mi = i;
} Test::Test(const Test& t)
{
// mi = t.getMi(); getMi() 非常函时,t 是对象的常引用,t 这个对象代表的引用代表只读对象,只能调用 const 函数;
mi = t.mi; // 这个时候可以,mi 是私有的,能够通过点操作符来访问吗?不是说只有对象自己的成员函数才可以访问自己的成员变量吗?这就引出了本文10中的问题;
} int Test::getMi() const
{
// mi = 2; 这里出错,不能够修饰 mi 的值;
return mi;
} int main()
{
Test t(); const Test t1(); // 实际工程开发中,并不一定每一个成员函数都是 const 的,这就意味着很少使用 const 对象,所以 一般情况都不用定义 const 成员函数; t1.mj = ; // 不能给只读变量 mj 赋值;const 修饰对象后,得到只读对象,其对应的成员变量值是不可以被改变的;只读变量:编译阶段不能出现在赋值符号左边,运行时能够改变; printf("t.getMi() = %d\n", t.getMi()); // 编译器显示 getMi() 是不可以被调用的,因为这个时候 t 是只读对象,但是 getMi() 这个时候不是 const 函数,加上后则可以了; return ;
}
10,成员函数和成员变量都是隶属于具体对象的吗?
1,每一个对象都拥有自己的一套成员变量,但是所有的对象共享一套成员函数;
11,从面向对象的角度:
1,对象由属性(成员变量)和方法(成员函数)构成;
从程序运行的角度:
1,对象由数据和函数构成:
1,数据可以位于栈、堆和全局数据区;
2,函数只能位于代码段;
1,代码段是只读的,在程序运行过程中是不可以被改变的,当编译器将最终的可执行程序编译好之后,代码段就被确定了,不可以被该;
2,对象可以动态的创建、动态的删除,对于数据而言,可以做到,栈数据、堆数据都可以动态的创建出来、动态的删除掉,但对于代码不可能;
3,在面相对象里面,由于程序的特性,天生的决定了成员函数是不能每个对象都有一套的,只可能是所有的对象共享一套成员函数,因为代码段是不可以动态的添加和删除的;
12,结论:
1,每一个对象拥有自己独立的属性(成员变量);
2,所有的对象共享类的方法(成员函数);
3,方法能够直接访问对对象的属性;
4,方法中的隐藏参数 this 用于指代当前对象;
1,所有的对象都可以调用一套成员函数,函数本身如何知道是那个对象调用的呢?
2,成员函数(和普通函数区别在于其多了一个隐藏的参数 this)分辨不同对象通过 this 指针来分辨;
3,this 指针通过接受不同的对象传来的地址来给成员函数分辨对象;
1,所以 const 函数只能调用 const 函数是因为要传递个被调用对象的 this 指针,但是调用函数的底层 const this 指针只能拷贝给被调用对象的底层 const this 指针;
13,成员函数的秘密编程实验:
#include <stdio.h> class Test
{
int mi;
public:
int mj;
Test(int i);
Test(const Test& t);
int getMi();
void print(); // 加这个函数是为了证明所有对象共用一套成员函数;
}; Test::Test(int i)
{
mi = i;
} Test::Test(const Test& t)
{
mi = t.mi; // 成员函数可以直接访问成员变量,因此拷贝构造函数这个特殊的成员函数就可以直接访问对象的成员变量,所以这里直接访问了 t 这个引用所指代的对象的成员变量是完全合法的;成员函数只有一套,它能直接访问任何所属类对象的成员变量,当然被调用时只传递一个对象的地址; } int Test::getMi()
{
return mi;
} void Test::print()
{
printf("this = %p\n", this);
} int main()
{
Test t1();
Test t2();
Test t3(); printf("t1.getMi() = %d\n", t1.getMi()); //
printf("&t1 = %p\n", &t1); // t1 的地址
t1.print(); // t1 的地址 printf("t2.getMi() = %d\n", t2.getMi()); //
printf("&t2 = %p\n", &t2); // t2 的地址
t2.print(); // t2 的地址 printf("t3.getMi() = %d\n", t3.getMi()); //
printf("&t3 = %p\n", &t3); // t3 的地址
t3.print(); // t3 的地址 return ;
}
1,实验说明:
1,在类的成员函数当中,有一个隐含的参数,它是一个指针,并且这个指针的值就是调用这个函数所对应的对象的地址;
2,也就是 this 指针指向当前对象;
3,成员函数有一个隐含的参数,这个参数是一个 this 指针,其指向当前对象;
4,每一个对象都有一套自己的成员变量,对象和对象之间的成员变量是独立的、不同的;但是每一个对象都共享一个类的成员函数;
14,小结:
1,对象的析构顺序与构造顺序相反;
2,const 关键字能够修饰对象,得到只读对象;
3,只读对象只能调用 const 成员函数;
4,所有对象共享类的成员函数;
5,隐藏的 this 指针用于表示当前对象;
C++中的析构顺序和cosnt对象的更多相关文章
- C++解析(12):初始化列表与对象构造顺序、析构顺序
0.目录 1.类成员的初始化 2.类中的const成员 3.对象的构造顺序 3.1 局部对象的构造顺序 3.2 堆对象的构造顺序 3.3 全局对象的构造顺序 4.对象的析构顺序 5.小结 1.类成员的 ...
- MFC中成员变量的声明顺序与析构顺序
第一次用博客,第一篇随笔,就写今天遇到的一个问题吧. 在VS2008的MFC对话框程序,窗口成员变量的声明顺序与其析构顺序相反,即,先声明的变量后析构,后声明的变量先析构.未在其他模式下测试. cla ...
- C++浅析——继承类中构造和析构顺序
先看测试代码,CTEST 继承自CBase,并包含一个CMember成员对象: static int nIndex = 1; class CMember { public: CMember() { p ...
- Promise对象及它在js中的执行顺序
关于Promise对象的学习及它的执行顺序 学习阮一峰老师的ES6入门后的记录 1.promise的定义 promise是一个对象,通常包裹着一个异步操作,promise对象提供一些接口的方法,返回一 ...
- JS对象 颠倒数组元素顺序reverse() reverse() 方法用于颠倒数组中元素的顺序。
颠倒数组元素顺序reverse() reverse() 方法用于颠倒数组中元素的顺序. 语法: arrayObject.reverse() 注意:该方法会改变原来的数组,而不会创建新的数组. 定义数组 ...
- C++语法小记---继承中的构造和析构顺序
继承中构造和析构的顺序 先父母,后客人,最后自己 静态变量和全局变量在最开始 析构和构造的顺序完全相反 #include <iostream> #include <string> ...
- C++ //继承中构造和析构顺序
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 class Base 6 { 7 pu ...
- iOS 中的 block 是如何持有对象的
Block 是 Objective-C 中笔者最喜欢的特性,它为 Objective-C 这门语言提供了强大的函数式编程能力,而最近苹果推出的很多新的 API 都已经开始原生的支持 block 语法, ...
- Effective C++学习笔记:初始化列表中成员列出的顺序和它们在类中声明的顺序相同
类成员的默认初始化顺序是按照声明顺序进行, 如果使用初始化列表初始化成员变量, 则必须按照成员变量的声明顺序进行; 否则, 在变量之间交替赋值时, 会产生, 未初始化的变量去赋值其他变量; 同时GCC ...
随机推荐
- (转载)自然语言处理中的Attention Model:是什么及为什么
转载说明来源:http://blog.csdn.net/malefactor/article/details/50550211 author: 张俊林 原文写得非常好! 原文: 要是关注深度学习在自然 ...
- JS分组
var SplitArray = function (N, Q) { var R = [], F; for (F = 0; F < Q.length;) R.push(Q.slice(F, F ...
- Java面试题系列(七)锁的原理
redis实现分布式锁 synchronized 和 reentrantlock的区别,偏向锁/轻量级锁/重量级锁的原理,能否从偏向锁直接升级成重量级锁
- 常见对象-Object类
Object类概述 是类层次结构的根类,每个类都直接或者间接继承该类. eg: 1.class Student extends Object{} //直接继承 2.class Student ext ...
- UVa 725 Division (枚举)
题意 : 输入正整数n,按从小到大的顺序输出所有形如abcde/fghij = n的表达式,其中a-j恰好为数字0-9的一个排列(可以有前导0),2≤n≤79. 分析 : 最暴力的方法莫过于采用数组存 ...
- sh_06_函数的返回值
sh_06_函数的返回值 def sum_2_num(num1, num2): """对两个数字的求和""" result = num1 + ...
- css实现不定宽高的div水平、垂直居中
一共有三个方案: 1,第一种方案主要使用了css3中transform进行元素偏移,效果非常好 这方法功能很强大,也比较灵活,不仅仅局限在实现居中显示. 兼容方面也一样拿IE来做比较,第二种方法IE ...
- 【Python】Python读取文件报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0x99 in position 20: illegal multibyte sequence
环境描述 text.txt 今天的天气不错 是个皻的选择 读取文件的代码 #!/usr/bin/python #-*- coding:UTF-8 -*- f = open(r'D:\Python\Py ...
- 大数据笔记(二十四)——Scala面向对象编程实例
===================== Scala语言的面向对象编程 ======================== 一.面向对象的基本概念:把数据和操作数据的方法放到一起,作为一个整体(类 c ...
- HDU6623 思维题(n分解成质因子的形式,问最小的幂是多少)
题目大意:给你一个数n,把它分解为素数的幂次的乘积的形式:n=p1^e1 * p2^e2 * .......pk^ek 求最小的幂次是多少 n=le18 分析: 首先我们肯定是不可以枚举1e18的因 ...