c++对象模型
文章平均质量分 92
对视频总结
哞哞哞咩咩咩
记录日常学习
展开
-
6.8 内存池概念,代码实现
#include <iostream>#include <vector>#include <ctime>using namespace std;namespace _nmsp1 //命名空间{ //一:内存池的概念和实现原理概述 //malloc:内存浪费,频繁分配小块内存,则浪费更加显得明显 //“内存池”,要解决什么问题? //(1)减少malloc的次数,减少malloc()调用次数就意味着减少对内存的浪费 //(2)减少malloc的调用次数原创 2020-09-28 19:30:09 · 52 阅读 · 0 评论 -
6.5 malloc(0)的问题
#include <iostream>#include <vector>#include <ctime>#include<algorithm>using namespace std;namespace _nmsp1{ //malloc来分配0个字节 void func() { char *p = (char*)malloc(0); if (NULL == p) printf("got a NULL pointer\n");原创 2020-09-25 20:37:03 · 98 阅读 · 0 评论 -
6.4局部静态对象,对象数组的构造析构和内存分配
一.局部静态对象的构造和析构#include <iostream>#include <vector>#include <ctime>#include<algorithm>using namespace std;namespace _nmsp1{ //一:局部静态对象的构造和析构 //a)如果我们不调用myfunc()函数,那么根本不会触发A的构造函数; //b)局部静态对象,内存地址是在编译期间就确定好的; //c)静态局部量刚开始也原创 2020-09-25 17:53:31 · 231 阅读 · 0 评论 -
6.1继承体系下对象构造步骤
1.虚函数的继续观察编译器会在构造函数里为虚函数指针赋值,所以:大家千万不要在构造函数中你自己的代码中使用诸如memcpy或者直接操作等手段,如memcpy(this,),(这样可能会修改虚函数表指针的值),导致调用虚函数时就可能造成系统崩溃。2.规则构造函数中调用虚函数,这里没有走虚函数表,而是直接通过虚函数地址,直接调用这个虚函数(静态方式调用)可能是因为还在构造函数中,没有构造完整,不宜采用虚函数表的方式而间接调用(虚函数里套个虚函数2,虚函数2又是虚函数表调用的-.-)...原创 2020-09-24 20:32:09 · 60 阅读 · 0 评论 -
5.11 inline函数回顾和扩展细节说
#include <iostream>#include <vector>#include <ctime>using namespace std;namespace _nmsp1 //命名空间{ //一:inline函数回顾 //使用inline之后,编译器内部会有一个比较复杂的测试算法来评估这个inline函数的复杂度; //可能会统计这个inline函数中,赋值次数,内部函数调用,虚函数调用等次数 ---权重 //(1)开发者写inline只是.原创 2020-09-14 11:11:59 · 73 阅读 · 0 评论 -
5.10 指向成员函数的指针及vcall进一步谈
#include <iostream>#include <vector>#include <ctime>using namespace std;namespace _nmsp1 //命名空间{ //一:指向成员函数的指针 //成员函数地址,编译时就确定好的。但是,调用成员函数,是需要通过对象来调用的; //所有常规(非静态)成员函数,要想调用,都需要 一个对象来调用它; //静态成员函数指针:需要一个普通的函数指针,而不是成员函数指针 class.原创 2020-09-14 00:04:51 · 129 阅读 · 0 评论 -
5.9 函数调用、继承关系性能说
#include <iostream>#include <vector>#include <ctime>using namespace std;namespace _nmsp1 //命名空间{ //一:函数调用中编译器的循环代码优化 //debug(会加入调试信息,运行时间会比较长)release(会做优化,运行时间短) //(1)优化循环,把循环优化成1条语句; //(2)在编译期间,编译器也具有运算能力,有些运算编译器在编译期间就能搞定;原创 2020-09-13 23:19:07 · 76 阅读 · 0 评论 -
5.8 RTTI运行时类型识别回顾与存储位置介绍
RTTI(运行时类型识别)简单回顾#include <iostream>using namespace std;class Base{public: virtual void f() { cout << "Base::f()" << endl; } virtual void g() { cout << "Base::g()" << endl; } virtual void h() { cout << "Base::h(原创 2020-09-12 22:05:01 · 170 阅读 · 0 评论 -
5.7多重继承第二基类对虚函数支持,返回类型协变,虚继承带虚函数
多重继承第二基类对虚函数支持的影响(this指针调整作用)#include <iostream>using namespace std;class Base{public: virtual void f() { cout << "Base::f()" << endl; } virtual void g() { cout << "Base::g()" << endl; } virtual void h() { cout <&l原创 2020-09-12 18:01:22 · 292 阅读 · 0 评论 -
5.6多继承虚函数深释,第二基类,虚析构必加
多继承下的虚函数#include <iostream>using namespace std;class Base{public: virtual void f() { cout << "Base::f()" << endl; } virtual void g() { cout << "Base::g()" << endl; } virtual void h() { cout << "Base::h()" <原创 2020-09-11 23:50:03 · 146 阅读 · 0 评论 -
5.5单继承虚函数,多继承趣味性测试和回顾
单继承下的虚函数#include <iostream>using namespace std;class Base{public: virtual void f() { cout << "Base::f()" << endl; } virtual void g() { cout << "Base::g()" << endl; } virtual void h() { cout << "Base::h()" <&原创 2020-09-11 21:16:11 · 68 阅读 · 0 评论 -
5.4静动态类型,绑定,坑点,多态体现深谈
静态类型和动态类型#include <iostream>using namespace std;class Base{public:};class Derive :public Base{public:};class Derive2 :public Base{public:};int main(){ //静态类型:对象定义时的类型,编译期间就确定好的 Base base; //base的静态类型是Base,没有动态类型,因为不是指针不是引用 Derive原创 2020-09-10 21:50:02 · 94 阅读 · 0 评论 -
5.3虚函数地址问题的vcall引入
#include <iostream>using namespace std;class MYACLS{public: virtual void myvirfunc1() { } virtual void myvirfunc2() { }};int main(){ //每个vcall代表唯一一个虚函数 printf("MYACLS::myvirfunc1()地址=%p\n", &MYACLS::myvirfunc1); //打印的是vcall函数(原创 2020-09-08 22:04:02 · 162 阅读 · 0 评论 -
5.2虚成员函数,静态成员函数调用方式
虚成员函数调用方式#include <iostream>using namespace std;class MYACLS{public: virtual void myvirfunc() { printf("myvirfunc()被调用,this = %p\n", this); myvirfunc2();//走虚函数表指针调用(不管进入此函数的对象是否多态) MYACLS::myvirfunc2(); //直接调用虚函数,效率更高。这种写法压制了虚拟机制,不再通过查原创 2020-09-08 20:09:53 · 185 阅读 · 0 评论 -
5.1普通成员函数调用方式
#include <iostream>using namespace std;class MYACLS{public: int m_i; void myfunc(int abc) { m_i += abc; }};//编译器视角 _ZN6MYACLS6myfuncEi是编译器给的函数名//void _ZN6MYACLS6myfuncEi(MYACLS *const this, int abc) //编译器会额外安插一个this指针,一般会扔到参数的开头//{//原创 2020-09-08 16:08:15 · 143 阅读 · 0 评论 -
4.11成员变量地址,偏移,指针等重申
#include <iostream>using namespace std;class MYACLS{public: int m_i; int m_j; int m_k;};void myfunc(int MYACLS::* mempoint, MYACLS& obj){ obj.*mempoint = 260; //注意写法}int main(){ //一:对象成员变量内存地址及其指针 MYACLS myobj; myobj.m_i = m.原创 2020-09-06 20:58:43 · 155 阅读 · 0 评论 -
4.10三层结构时虚基类表内容分析
#include <iostream>using namespace std;class Grand //爷爷类{public: int m_grand;};class A1 : virtual public Grand{public: int m_a1;};class A2 : virtual public Grand{public: int m_a2;};class C1 :public A1, public A2{public: int m_原创 2020-09-06 20:31:52 · 120 阅读 · 0 评论 -
4.9两层结构时虚基类表内容分析
虚基类表内容之1-8字节内容分析#include <iostream>using namespace std;class Grand //爷爷类{public: int m_grand;};class A1 : virtual public Grand{public: int m_a1;};class A2 : virtual public Grand{public: int m_a2;};class C1 :public A1, public A2原创 2020-09-03 21:25:56 · 107 阅读 · 0 评论 -
4.8虚基类问题的提出和初探
虚基类(虚继承/虚派生)问题的提出传统多重继承造成的 :空间问题,效率问题,二义性问题#include <iostream>#include <vector>using namespace std;class Grand //爷爷类{public: int m_grand;};class A1 : public Grand{public:};class A2 : public Grand{public:};class C1 :pub原创 2020-09-03 11:25:11 · 76 阅读 · 0 评论 -
4.7多重继承数据布局与this调整深谈
单一继承数据成员布局this指针偏移知识补充this指针,加上偏移值 就的能够访问对应的成员变量,比如m_bi = this指针+偏移值#include <iostream>using namespace std;class Base{public: int m_bi; Base() { printf("Base::Base()的this指针是:%p!\n", this);//打印父类this指针 };};class MYACLS :public Base{pu原创 2020-09-02 17:38:02 · 125 阅读 · 0 评论 -
4.6单类单继承虚函数下的数据成员布局
在64位下运行单个类带虚函数的数据成员布局类中引入虚函数时,会有额外的成本付出(1)编译的时候,编译器会产生虚函数表,参考三章五节(2)对象中会产生 虚函数表指针vptr,用以指向虚函数表的(3)增加或者扩展构造函数,增加给虚函数表指针vptr赋值的代码,让vptr指向虚函数表;(4)如果多重继承,比如你继承了2个父类,每个父类都有虚函数的话,每个父类都会有vptr,那继承时,子类就会把这两根vptr都继承过来,如果子类还有自己额外的虚函数的话,子类与第一个基类共用一个vptr(三章四节)(自原创 2020-09-02 16:02:00 · 81 阅读 · 0 评论 -
4.5 单一继承下的数据成员布局
简单继承成员布局#include <iostream>using namespace std;class FAC //父类{public: int m_fai; int m_faj;};class MYACLS :public FAC //子类{public: int m_i; int m_j;};int main(){ //第五节 单一继承下的数据成员布局 printf("FAC::m_fai = %d\n", &FAC::m_fai);原创 2020-09-02 11:25:11 · 66 阅读 · 0 评论 -
3.虚函数
所有代码运行在64位系统环境1.虚函数表指针位置分析#include <iostream>using namespace std;class A{public: int i; //4字节 virtual void testfunc() {} //虚函数,vptr8字节。};int main(){ //虚函数表指针位置分析 //类:有虚函数,这个类会产生一个虚函数表。 //类对象,有一个指针,指针(vptr)会指向这个虚函数表的开始地址。 A aobj; in原创 2020-08-26 21:15:40 · 147 阅读 · 0 评论 -
2.对象
所有代码在x64下运行一.类对象所占用的空间大小#include <iostream>using namespace std;class A{public: void func() {}; //成员函数 void func1() {}; //成员函数 void func2() {}; //成员函数 //char ab; //成员变量,char类型占一个字节内存 int ab; //int类型占4个字节};class B {};//类对象所占用的空间int m原创 2020-07-29 14:42:19 · 167 阅读 · 0 评论 -
4.4数据语义学-数据成员存取
本文C++类的static的说明,参考C++类中的static类内static变量static变量不像普通的变量,static变量独立于一切类对象处在。static修饰的变量先于对象存在,所以static修饰的变量要在类外初始化。因为static是所有对象共享的东西嘛,必须要比对象先存在的。静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问;静态成员函数可不建立对象就可以被使...原创 2020-04-05 17:45:04 · 139 阅读 · 0 评论 -
4.3数据语义学-数据成员分布
边界调整,字节对齐某些因素会导致成员变量之间排列不连续,就是边界调整(字节对齐),调整的目的是提高效率,编译器自动调整;往成员之间填补一些字节,使用类对象的sizoef字节数凑成 一个4的整数倍,8的整数倍;为了统一字节对齐问题,引入一个概念叫一字节对齐(不对齐);在类前面加上#pragma pack(1),类后面加上#pragma pack() 取消指定对齐,恢复默认对齐方式;普通成员变量...原创 2020-04-05 15:49:34 · 143 阅读 · 0 评论 -
4.2数据语义学-进程内存空间布局
进程的五个段当运行一个可执行文件时,操作系统就会把这个可执行文件加载到内存;此时进程有一个虚拟的地址空间(内存空间)BSS段:通常是指用来存放程序中未初始化的全局变量(包括静态变量)或者初始化为0的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。BSS段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小。数...原创 2020-04-05 01:24:21 · 105 阅读 · 0 评论 -
4.1数据语义学-数据成员绑定时机
全局变量和类成员变量同名#include <iostream>using namespace std;string myvar= "I Love China!"; //全局量,字符串型//定义一个类class A{public: int myfunc(); int myvar; //同全局变量名相同,但类型不同。 };int A::myfunc()//成员...原创 2020-04-04 21:57:22 · 205 阅读 · 0 评论