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

1. 回归本质

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

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

  ②class与struct遵循相同的内存对齐规则

  ③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)调用成员函数时对象地址作为参数隐式传递

时间: 2024-10-01 07:16:39

第50课 C++对象模型分析(上)的相关文章

第50 课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() { re

第51课 C++对象模型分析(下)

1. 单继承对象模型 (1)单一继承 [编程实验]继承对象模型初探 #include <iostream> using namespace std; class Demo { protected: int mi; int mj; public: //虚函数 virtual void print() { cout << "mi = " << mi << ", " << "mj = " &l

第51课 继承对象模型分析——多态的本质分析

多态的本质分析 用C写面向对象,用C实现多态 #ifndef _51_2_H_ #define _51_2_H_ typedef void Demo; typedef void Derived; 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* pThi

【自动语音识别课程】第二课 语音信号分析

[传送门] [自动语音识别课程]第一课 统计语音识别介绍 原文地址:http://blog.csdn.net/joey_su/article/details/36414877 转载请注明出处,欢迎交流. 概述 针对ASR的语音信号分析 特征 频谱分析 倒谱分析 标准特征:MFCC和PLP分析 动态特征 第一课的结尾提到了语音识别的框图,下图展示了信号分析技术在语音识别系统中的位置: 我们先来认识下语音的产生过程: 语音是在发音器官和声道共同作用下产生的.说话时,声带振动发出具有一定周期特性(基音

C++--C++对象模型分析、c++中的抽象类和接口

一.C++对象模型分析 A.class是一种特殊的struct1.在内存中class依旧可以看作变量的合集2.在class域struct遵循相同的内存对齐规则3.class中的成员函数与成员变量是分开存放的--每个对象有独立的成员变量,所有对象共享类中的成员函数Q:class与struct的内存占用情况? #include <iostream> #include <string> using namespace std; class A { int i; int j; char c

C++--第17课 - 继承与多态 - 上

第17课 - 继承与多态 - 上 引入: 如果子类定义了与父类中原型相同的函数会发生什么? 1. 函数重写 在子类中定义与父类中原型相同的函数,函数重写只发生在父类与子类之间. 父类中被重写的函数依然会继承给子类,默认情况下子类中重写的函数将隐藏父类中的函数,通过作用域分辨符::可以访问到父类中被隐藏的函数. #include <cstdlib> #include <iostream> using namespace std; class Parent { public: void

2016-09-02 16:50:15 webqq 协议分析

2016-09-02 16:50:15 webqq 协议分析 1. 扫描二维码登录 https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid=501004106&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&a

C++语言学习(十三)——C++对象模型分析

C++语言学习(十三)--C++对象模型分析 一.C++对象模型分析 1.类对象模型的内存布局 class是一种特殊的struct,class与struct遵循相同的内存对齐原则,class中的成员函数与成员变量是分开存放的,每个对象拥有独立的成员变量,所有的对象共享类中的成员函数.运行时,类对象退化为结构体的形式:A.所有成员变量在内存中依次排布B.由于内存对齐的存在,成员变量间可能存在内存间隙C.可以通过内存地址访问成员变量D.访问权限关键字在运行时失效 #include <iostream

第五十课、c++对象模型分析(上)

一.c++对象模型之成员变量 1.class是一种特殊的struct (1).在内存中class依旧可以看做是变量的集合 (2).class与struct遵循相同的内存对齐规则 (3).class中的成员函数和成员变量是分开存储的 A.每个对象有独立的成员变量 B.所有对象共享类中的成员函数 2.运行时的对象退化为结构体的形式 (1).所有成员变量在内存中依次分布 (2).成员变量间可能存在内存间隙 (3).可以通过内存地址直接访问成员变量 (4).访问权限关键字在运行时失效 #include<