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

狂风中的少年 提交于 2019-12-18 09:52:55

1. 回归本质

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

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

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

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

 

【编程实验】对象内存布局初探

#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; //24 bytes

    cout << "sizeof(a) = " << sizeof(a) << endl; //24 bytes

    cout << "sizeof(B) = " << sizeof(B) << endl; //24 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) = 24

sizeof(a) = 24

sizeof(B) = 24

 

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++示例

#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\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; //相当于私有变量,不能直接通过this指针(d)来访问

   

    Demo_Free(d);

   

    return 0;

}

 

 

3. 小结

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

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

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

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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!