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 = ;
    p->j = ;
    p->c = 'C';
    p->d = 3.14;

    a.print(); //class中的private成员被改变

    ;
}
/*输出结果
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(, );

    cout <<
    cout <<
    cout <<
    cout << ) << endl;    

    ;
}

//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));

    )
    {
        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(, );  //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());  //d->add(3); 

    //d->mi = 100; //相当于私有变量,不能直接通过this指针(d)来访问

    Demo_Free(d);

    ;
}

3. 小结

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

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

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

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

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

  1. 第50 课C++对象模型分析——成员变量(上)

    C++对象模型,其实就是C++中的对象在内存中是如何排布的.C++中的对象包含了成员变量和成员函数,其实就是研究C++中的类对象它的成员变量和成员函数在内存中是如何排布的. 回归本质class 是一种 ...

  2. 第50 课C++对象模型分析——成员函数(上)

    类中的成员函数位于代码段中调用成员函数时对象地址作为参数隐式传递成员函数通过对象地址访问成员变量C++语法规则隐藏了对象地址的传递过程 #include<iostream> #includ ...

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

    1. 单继承对象模型 (1)单一继承 [编程实验]继承对象模型初探 #include <iostream> using namespace std; class Demo { protec ...

  4. Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation

    原文:Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ...

  5. 第24课 - #pragma 使用分析

    第24课 - #pragma 使用分析 1. #pragma简介 (1)#pragma 是一条预处理器指令 (2)#pragma 指令比较依赖于具体的编译器,在不同的编译器之间不具有可移植性,表现为两 ...

  6. R与数据分析旧笔记(六)多元线性分析 上

    > x=iris[which(iris$Species=="setosa"),1:4] > plot(x) 首先是简单的肉眼观察数据之间相关性 多元回归相较于一元回归的 ...

  7. C++对象模型的那些事儿之一:对象模型(上)

    前言 很早以前就听人推荐了<深入理解C++对象模型>这本书,从年初买来到现在也只是偶尔翻了翻,总觉得晦涩难懂,放在实验室上吃灰吃了好久.近期由于找工作对C++的知识做了一个全面系统的学习, ...

  8. 拥有的50个CSS代码片段(上)

    1. CSS 重置 ;;;font-size: 100%; font: inherit; vertical-align: baseline; outline: none; -webkit-box-si ...

  9. 知识小罐头05(tomcat8请求源码分析 上)

    这一篇我们不看源码,就大概理一下Tomcat内部组成部分!前面花费了两篇博客的篇幅来说说了一般的maven web项目并部署到tomcat运行,其实都是为这篇做铺垫的! 其实我下载了tomcat7,t ...

随机推荐

  1. linux压缩和解压命令总结

    一.tar.gz tar -xzvf 二.tar.bz2 tar.bz2 解压命令 bzip2 -d  gcc-4.1.0.tar.bz2---上面解压完之后执行下面的命令.执行成功后,会解压生成一个 ...

  2. Visual Studio图片注释image-comments扩展

            有一个开源的Visual Studio小工具image-comments,它用于在源代码注释中插入图片,您可以到这儿下载.目前支持Visual Studio 2010/2012 Sta ...

  3. 常用Keytool 命令

    常用Keytool 命令Keytool 是一个JAVA环境下的安全钥匙与证书的管理工具.它管理一个存储了私有钥匙和验证相应公共钥匙的与它们相关联的X.509 证书链的keystore(相当一个数据库, ...

  4. C++ 面向对象的三个特点--继承与封装(一)

    面试的时候经常会有很多概念性的东西,许久不用都会很生疏,特意整理一下方便自己以后不记得了可以查看一下,也顺便帮助自己复习一下. 概念 继承是面向对象程序设计的一个重要特性,它允许在既有类的基础上创建新 ...

  5. elasticseach multi-field的实际用途

    下面是multi-field的介绍: multi_field 多域类型允许你对同一个值以映射的方式定义成多个基本类型 core_types . 这个非常有用,比如,如果你定义一个 string 类型的 ...

  6. SQL对字符串数组的处理

    一,用临时表作为数组 复制代码代码如下: create function f_split(@c varchar(2000),@split varchar(2)) returns @t table(co ...

  7. 解决ArcGIS10.3属性表中文乱码问题

    问题描述:在10.3刚出为不久,就发现有时属性表会出现中文乱码的问题. 解决方法:在Cmd命令行中输入以下命令: reg add HKEY_CURRENT_USER\Software\ESRI\Des ...

  8. 读取XML绑定TreeNode

    <asp:TreeView ID="treeview" OnClick="TreeViewCheckBox_Click()" runat="se ...

  9. 在Seismic.NET下用最少的语句写出一个剖面显示程序

    用Seismic.NET开发地震剖面显示程序可以节省大量的时间,下面的代码展开了如何用最少的代码显示一个SEGY文件. // 用一行语句把 reader, pipeline, view 和 plot ...

  10. android:descendantFocusability=”blocksDescendants”的用法

    android:descendantFocusability用法简析 开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承B ...