对象模型分析

Posted 学习只为旅行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对象模型分析相关的知识,希望对你有一定的参考价值。

对象模型实际上就是探讨对象在内存中如何排布,包含成员变量、成员函数


仅仅是访问权限的差别:class默认private,struct默认public


字节对齐知识点!int四个字节、char本来是1个字节但是由于内存对齐就是四个字节了!double是八个字节,加起来就是20个字节!

#include <iostream>
#include <string>

using namespace std;
//成员变量和成员函数在内存排不上是不一样的
//成员变量可能在栈、堆、全局变量区
//而成员函数只可能在代码段
class A
{
    int i;
    int j;
    char c;
    double d;
public:
    void print()
    {
        cout << "i = " << i << ", "
             << "j = " << j << ", "
             << "c = " << c << ", "
             << "d = " << d << endl;
    }
};

struct B
{
    int i;
    int j;
    char c;
    double d;
};

int main()
{
    A a;
    
    cout << "sizeof(A) = " << sizeof(A) << endl;    // 20 bytes
    cout << "sizeof(a) = " << sizeof(a) << endl;    // 20 bytes
    cout << "sizeof(B) = " << sizeof(B) << endl;    // 20 bytes
    
    a.print();
    
    //reinterpret_cast:
    //1、指针类型间的强制转换
    //2、整数和指针间的转换
    B* p = reinterpret_cast<B*>(&a);
    
    p->i = 1;
    p->j = 2;
    p->c = 'c';
    p->d = 3;
    
    a.print();
    
    p->i = 100;
    p->j = 200;
    p->c = 'C';
    p->d = 3.14;
    
    a.print();
    
    return 0;
}



访问权限关键字像private,只在编译期间有效,编译器进行语法检查而已,在运行时都是二进制!

成员函数可以使用this指针,这个指针的本质就是对象的地址!

#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
#include "50-2.h"
#include "malloc.h"

//结构体代表类,也反映了C++class本质就是结构体
struct ClassDemo
{
    int mi;
    int mj;
};

Demo* Demo_Create(int i, int j)
{
    struct ClassDemo* ret = (struct ClassDemo*)malloc(sizeof(struct ClassDemo));
    
    if( ret != NULL )
    {
        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);
}

#include <stdio.h>
#include "50-2.h"

int main()
{
    Demo* d = Demo_Create(1, 2);             // Demo* d = new Demo(1, 2);
    
    printf("d.mi = %d\\n", Demo_GetI(d));     // d->getI();
    printf("d.mj = %d\\n", Demo_GetJ(d));     // d->getJ();
    printf("Add(3) = %d\\n", Demo_Add(d, 3));    // d->add(3);
    
    // d->mi = 100;//报错,看下面解释,简单来说就是void*变量只能接受地址值,不能用来访问!
    
    Demo_Free(d);
    
    return 0;
}

打印结果1 2 6

void*类型定义的指针变量只接收对象的地址,没有对象的类型概念。所以该指针变量是不能直接用
指针变量”去访问对象的,只能经强制类型转换后才能“间接”访问:*(type*)指针变量,必须
给出正确的type!
比如:
void
accept_request(void *pclient)
{
int client = *(int *)pclient; //这才是正确的写法
。。。
}
如果按照下面的写法,就会报上面的错误
void *accept_request(void *pclient)
{
int client = *pclient; //错误的写法
。。。
}

小结

以上是关于对象模型分析的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 jquery 从 asp.net 视图模型中动态删除行而不删除集合中的其余下一个对象

方法与对象内存分析

为啥 Python 不使用对象 .save() 将我的模型保存到数据库?

对象模型分析(下)

VSCode自定义代码片段12——JavaScript的Promise对象

VSCode自定义代码片段12——JavaScript的Promise对象