• 第50课 C++对象模型分析(上)


    1. 回归本质

    (1)class是一种特殊的结构体(struct)

      ①在内存class依旧可以看作变量的集合

      ②classstruct遵循相同的内存对齐规则

      ③class中的成员函数成员变量分开存放的。即每个对象独立的成员变量,但所有对象共享类中的成员函数

    (2)值得思考的问题:两者相等

        

    【编程实验】C++对象内存布局初探  50-1.cpp

    #include <iostream>
    
    #include <string>
    
     
    
    using namespace std;
    
     
    
    class A
    
    {
    
        //默认访问权限为private
    
        int i;
    
        int j;
    
        char c;
    
        double d;
    
     public:
    
        void print()
    
        {
    
            cout << "i = " << i << ", "
    
                 << "j = " << j << ", "
    
                 << "c = " << c << ", "
    
                 << "d = " << d << endl;
    
        }
    
    };
    
     
    
    struct B
    
    {
    
        //默认访问权限为public
    
        int i;
    
        int j;
    
        char c;
    
        double d;  
    
    };
    
     
    
    int main()
    
    {
    
        A a;
    
        //class和struct在内存布局上是一样的。大小相同
    
        cout << "sizeof(A) = " << sizeof(A) << endl; //20 bytes
    
        cout << "sizeof(a) = " << sizeof(a) << endl; //20 bytes
    
        cout << "sizeof(B) = " << sizeof(B) << endl; //20 bytes  
    
     
    
        cout << endl;
    a.print(); cout
    << endl; B* p = reinterpret_cast<B*>(&a); //将类强制转化结构体 //利用结构体对类的private成员进行赋值(注意是private成员) //说明class在运行时,private访问权限只在编译期起作用。
    p->i = 100; p->j = 200; p->c = 'C'; p->d = 3.14; a.print(); //class中的private成员被改变 return 0; }

    /*输出结果

    sizeof(A) = 20

    sizeof(a) = 20

    sizeof(B) = 20

    i = 4202544, j = 65535, c =  , d = 8.69169e-311

    i = 100, j = 200, c = C, d = 3.14

    */

    (2)运行时对象退化为结构体的形式类的成员变量的内存布局

      ①所有成员变量内存依次排布

      ②成员变量间可能存在内存空隙

      ③可以通过内存地址直接访问成员变量

      ④访问权限关键字运行时失效

    2. C++对象模型类的成员函数的内存布局

    (1)中的成员函数位于代码段中

    (2)调用成员函数对象地址作为参数隐式传递

    (3)成员函数通过对象地址访问成员变量

    (4)C++语法规则隐藏对象地址传递过程

    【编程实验】对象本质分析(用C写面向对象)

    //C++示例  50-2.cpp

    #include <iostream>
    
    #include <string>
    
     
    
    using namespace std;
    
     
    
    class Demo
    
    {
    
        int mi;
    
        int mj;
    
     public:
    
        Demo(int i, int j)
    
        {
    
            mi = i;
    
            mj = j;
    
        }
    
       
    
        int getI()
    
        {
    
            return mi;
    
        }
    
       
    
        int getJ()
    
        {
    
            return mj;
    
        }
    
       
    
        int add(int value)
    
        {
    
            return mi + mj + value;
    
        }
    
    };
    
     
    
    int main()
    
    {
    
        Demo d(1, 2);
    
       
    
        cout << "sizeof(d) = " << sizeof(d) << endl;  //8
    
        cout << "d.getI() = " << d.getI() << endl;    //1
    
        cout << "d.getJ() = " << d.getJ() << endl;    //2
    
        cout << "d.add(3) = " << d.add(3) << endl;    //6
    
       
    
        return 0;
    
    }

    //C语言模拟面向对象

    //50-2.h

    #ifndef _50_2_H_
    
    #define _50_2_H_
    
     
    
    typedef void Demo;
    
     
    
    //声明成员函数(接口)
    
    Demo* Demo_Create(int i, int j);
    
    int Demo_GetI(Demo* pThis);
    
    int Demo_GetJ(Demo* pThis);
    
    int Demo_Add(Demo* pThis, int value);
    
    void Demo_Free(Demo* pThis);
    
     
    
    #endif

    //50-2.c

    #include "50-2.h"
    
    #include <malloc.h>
    
     
    
    //利用C语言来实现面向对象
    
    //定义结构体
    
    struct ClassDemo
    
    {
    
       int mi;
    
       int mj;
    
    };
    
     
    
    //实现各成员函数(带this指针)
    //构造函数
    Demo* Demo_Create(int i, int j) { struct ClassDemo* ret = (struct ClassDemo*)malloc(sizeof(struct ClassDemo)); if(ret != 0) { ret ->mi = i; ret ->mj = j; } return ret; } int Demo_GetI(Demo* pThis) { struct ClassDemo* obj = (struct ClassDemo*)pThis; return obj->mi; } int Demo_GetJ(Demo* pThis) { struct ClassDemo* obj = (struct ClassDemo*)pThis; return obj->mj; } int Demo_Add(Demo* pThis, int value) { struct ClassDemo* obj = (struct ClassDemo*)pThis; return obj->mi + obj->mj + value; } //析构函数 void Demo_Free(Demo* pThis) { free(pThis); }

    //main.c

    #include <stdio.h>
    
    #include "50-2.h"
    
     
    
    int main(void)
    {
    
       Demo
    * d = Demo_Create(1, 2); //Demo* d = new Demo(1, 2); //各函数调用中,传入this指针:d printf("d.mi = %d ", Demo_GetI(d)); //d->getI(); printf("d.mj = %d ", Demo_GetJ(d)); //d->getJ(); printf("Add(3) = %d ", Demo_Add(d, 3)); //d->add(3); //d->mi = 100; //相当于私有变量,不能直接通过this指针(d)来访问 Demo_Free(d); return 0; }

    3. 小结

    (1)C++中的类对象内存布局上与结构体相同

    (2)成员变量成员函数内存分开存放

    (3)中的成员变量struct遵循相同的内存对齐规则

    (4)中的成员函数位于代码段中

    (5)访问权限关键字运行时失效

    (6)调用成员函数对象地址作为参数隐式传递

  • 相关阅读:
    基础之实战猜年龄游戏
    基本运算符与if while详解:
    while循环练习:
    常量与格式化输出练习
    Flask基础(05)-->路由的基本定义
    Flask基础(04)-->相关配置参数
    Flask基础(03)-->创建第一个Flask程序
    Flask基础(02)-->搭建Flask项目虚拟环境
    Flask基础(01)-->Flask框架介绍
    Flask实战第61天:帖子板块过滤显示
  • 原文地址:https://www.cnblogs.com/hoiday/p/10200903.html
Copyright © 2020-2023  润新知