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


    • 回归class(对象)的本质
    1. class是一种特殊的struct
    2. 在内存中class依旧可以看作变量的集合
    3. class与struct遵循相同的内存对齐规则
    4. class中的成员函数与成员变量是分开存放的,每个对象有独立的成员变量,所有对象共享类中的成员函,。
    • 思考一个问题
    • 对象内存布局实验
     1 // 对象内存布局实验.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
     2 //
     3 #include <iostream>
     4 #include <string>
     5 using namespace std;
     6 class A
     7 {
     8         int a;
     9         int b;
    10         char c;
    11         double d;
    12 public:
    13         void print()
    14         {
    15                cout << "a=" << a << ","
    16                         << "b=" << b << ","
    17                         << "c=" << c << ","
    18                         << "d=" << d << endl;
    19         }
    20         
    21 };
    22 struct B
    23 {
    24         int a;
    25         int b;
    26         char c;
    27         double d;
    28 };
    29 int main()
    30 {
    31         A a;
    32         a.print();
    33         cout << "sizeof(A) = " << sizeof(A) << endl;
    34         cout << "sizeof(a) = " << sizeof(a) << endl;
    35         cout << "sizeof(B) = " << sizeof(B) << endl;
    36         B* p = reinterpret_cast<B*>(&a);
    37         p->a = 1;
    38         p->b = 2;
    39         p->c = 'C';
    40         p->d = 1.234;
    41         a.print();
    42 }
    • 运行结果
    a=-858993460,b=-858993460,c=?d=-9.25596e+61
    sizeof(A) = 24
    sizeof(a) = 24
    sizeof(B) = 24
    a=1,b=2,c=C,d=1.234
    • 运行时的对象退化为结构体的形式
    1. 所有成员变量在内存中依次排布
    2. 成员变量可能存在内存空隙
    3. 可以通过内存地址直接访问成员变量
    4. 访问权限关键字在运行时失效
    5. 类中的成员函数位于代码段中
    6. 调用成员函数时对象地址作为参数隐式传递
    7. 成员函数通过对象地址访问成员变量
    8. C++语法规则隐藏了对象地址的传递过程
    • 实验:用C语言来写面向对象,加深C++面向对象的理解。
    main.c
     1 #include "stdio.h"
     2 #include "oop.h"
     3 int main()
     4 {
     5         struct OOP* THIS = NULL;
     6         //【step1】执行“构造函数”
     7         THIS = (struct OOP*)Great_Object(1,2);
     8         //【step2】执行成员函数,成员函数必须带有对象地址,通过对象地址访问成员变量
     9         printf("THIS->value1=%d
    ", GET_Value1(THIS));
    10         printf("THIS->value2=%d
    ", GET_Value2(THIS));
    11         //【step3】执行“析构函数”
    12         Free_Object(THIS);
    13 }
    14 
     
    OOP.c
     1 #include "oop.h"
     2 #include "stdio.h"
     3 DEMO* Great_Object(int i, int j)
     4 {
     5         struct OOP* Object = (struct OOP*)malloc(sizeof(struct OOP));
     6         if (Object!=NULL)
     7         {       
     8                Object->value1 = 1;
     9                Object->value2 = 2;
    10         }
    11         return Object;
    12 }
    13 int GET_Value1(DEMO* pthis)
    14 {
    15         struct OOP* ret = (struct OOP*)pthis;
    16         return ret->value1;
    17 }
    18 int GET_Value2(DEMO* pthis)
    19 {
    20         struct OOP* ret = (struct OOP*)pthis;
    21         return ret->value2;
    22 }
    23 void Free_Object(DEMO* pthis)
    24 {
    25         free(pthis);
    26 }
    OOP.h
    #ifndef _OOP_H_
    #define _OOP_H_
    typedef void DEMO;
    struct OOP
    {
            int value1;
            int value2;
    };
    //【step1】模拟C++的构造函数,需要返回this指针
    DEMO* Great_Object(int i,int j);
    //【step2】定义成员函数,获取成员变量的值,需要传递对象的地址
    int GET_Value1(DEMO* pthis);
    //【step2】定义成员函数,获取成员变量的值,需要传递对象的地址
    int GET_Value2(DEMO* pthis);
    //......
    //【step3】模拟C++中的析构函数
    void Free_Object(DEMO* pthis);
    #endif
    • 小结
    1. C++中的类对象在内存布局上与结构体相似
    2. 成员变量和成员函数在内存中分开存放
    3. 访问权限关键字在运行时失效
    4. 调用成员函数时对象地址作为参数隐式传递
     
    主要记录的是学习听课的笔记
  • 相关阅读:
    Python安装
    Python的种类
    Windows server 下 DNS服务器 实现递归查询和循环查询的配置方法
    Command Injection_low、Medium、high、Impossible
    Brute Force_impossible
    Brute Force_high
    Brute Force_medium
    Brute Force_low
    脚本黑客1----HTML基础笔记
    windows服务器大量端口被dns.exe占用的解决方法
  • 原文地址:https://www.cnblogs.com/chengeputongren/p/12250352.html
Copyright © 2020-2023  润新知