1.1对象模型分析 1.1.1 对象模型分析的本质
C++中的对象分为两个部分:对象的成员变量和对象的成员函数,对象模型分析就是对对象的成员变量和成员函数进行分析。 1.1.2类对象的本质 class 是一种特殊的struct在内存中class依旧可以看做变量的集合class 与struct 遵循相同的内存对齐规则class中的成员变量和成员函数是分开存放的 (1)每个对象都有独立的成员变量(在堆,栈,全局数据区分配内存) (2)成员函数本质是函数,只能在代码区分配内存,所有类对象共享类中的成员函数。1.1.3实例代码
#include <iostream> using namespace std; class Test { char a; int b; int c; double d; public: void print() { cout <<" a= "<<a <<" b= "<< b<<" c = "<<c <<" d= "<<d<<endl; } }; struct ST { char a; int b; int c; double d; }; int main() { Test t1; ST *st; st =reinterpret_cast<ST*>(&t1); st->a ='A'; st->b=10; st->c=20; st->d=3.14; t1.print(); return 0; }运行结果: 1.1.4运行时对象退化成结构体的形式
所有成员变量在内存中依次排布成员变量间可能存在内存空隙可以通过内存地址直接访问成员变量访问权限关键字在运行时失效总结
类中的成员函数位于代码段中调用成员函数时,对象地址作为参数隐式传递(this指针)成员函数通过对象地址访问成员变量C++ 语法规则汇总隐藏了对象地址的传递过程。1.1.5代码实例 下面是 .cpp文件
#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; cout << "d.getI() = " << d.getI() << endl; cout << "d.getJ() = " << d.getJ() << endl; cout << "d.add(3) = " << d.add(3) << endl; return 0; }使用C语言完成面向对象的程序
下面是.c 文件
#include <stdio.h> #include <stdlib.h> #include "Test.h" struct Test { int i ; int j; }; Demo* Demo_create(int i,int j) { struct Test * t = (struct Test *)malloc(sizeof(struct Test)); if(t != NULL) { t->i =i; t->j =j; } return t; } int GetI(Demo* demo) { struct Test * t =(struct Test * )demo; return t->i; } int GetJ(Demo * demo) { struct Test * t =(struct Test*) demo; return t->j; } int SetI(Demo *demo ,int i) { struct Test * t =(struct Test*) demo; t->i =i; } int SetJ(Demo * demo,int j) { struct Test * t =(struct Test*) demo; t->j =j; } void Demo_free(Demo* demo) { free(demo); }下面是.h文件
#ifndef __TEST_H #define __TEST_H typedef void Demo; //和C++中private的作用相同 Demo* Demo_create(int i,int j); int GetI(Demo* demo); int GetJ(Demo * demo); int SetI(Demo *demo ,int i); int SetJ(Demo * demo,int j); void Demo_free(Demo* demo); #endif下面是 main.c
#include <stdio.h> #include <stdlib.h> #include "Test.h" int main() { Demo *d = Demo_create(10,20); printf("i =%d\n",GetI(d)); printf("j= %d\n",GetJ(d)); Demo_free(d); return 0; }遇到问题有,在编写的过程中将main文件定义成了main.cpp导致程序找不到函数入口。
1.2继承中对象模型初探 1.2.1 继承中对象模型
继承中子类是由父类成员叠加子类新成员得到的1.2.2 继承模型初探示例
代码示例 class Demo { protected: int mi; int mj; }; class Derived : public Demo { protected: int mk; public: Derived(int i ,int j ,int k) { mi = i; mj = j; mk = k; } void print() { cout<< "mi = " <<mi <<endl; cout<< "mj = " <<mj <<endl; cout<< "mj = " <<mk <<endl; } }; struct Test { int mi; int mj; int mk; }; int main() { cout<<"sizeof(Demo) "<<sizeof(Demo)<<endl; // 8 //如果函数是virtual的就是 12 cout<<"sizeof(Derived) "<<sizeof(Derived)<<endl; //12 //如果函数是virtual的就是 16 Derived d(1,2,3); Test *p = reinterpret_cast<Test*>(&d); d.print(); cout<<endl; cout<<"after change "<<endl; p->mi =10; p->mj= 20; p->mk =30; d.print(); return 0; } 实验说明 : 继承以后成员的分布是父类的成员在前面,子类的成员在后面实验说明二: 存在虚函数的时候,会在结构体中自动加入一个指向虚函数表的指针1.3 C++中多态的实现 1.3.1多态原理
当声明虚函数的时候,编译器会在类中生成一个虚函数表虚函数表是一个存储成员函数的数据结构虚函数表是由编译器自动生成和维护的virtual成员函数会被编译器放入虚函数表中存在虚函数时,每个对象中都与一个指向虚函数变的指针1.3.2 多态VS虚函数
多态:是面向对象程序设计中的一个概念,相同的行为方式,不同的行为结果虚函数: C++中通过虚函数进行实现的。 1.3.3 模型图解上图中 子类的虚函数表中应该是 int Child::add(int value);每一个对象都对应属于自己的虚函数表 调用效率对比: 虚函数 < 普通成员函数1.3.3 多态本质 .h文件
#ifndef __TEST_H #define __TEST_H typedef void Parent; typedef void Child; Parent * parent_create(int i ,int j); int getI(Parent * parent); int getJ(Parent* parent); int parent_add(Parent* parent ,int value); void parent_free(Parent* parent); Child * child_creat(int i,int j ,int k); int getK(Child * child); int child_add(Child* child,int value); #endif.c文件
#include <stdio.h> #include <stdlib.h> #include "Test.h" static int parent_virtual_add(Parent* parent ,int value); static int child_virtual_add(Child* child,int value); struct classParent { struct vtable * vptr; int i; int j; }; struct classChild { struct classParent p; int k; }; struct vtable { int (*pAdd)(Parent* ,int); }; struct vtable parent_virtual_table= { parent_virtual_add }; struct vtable child_virtual_table= { child_virtual_add }; Parent * parent_create(int i ,int j) { struct classParent * p = (struct classParent*)malloc(sizeof(struct classParent)); if(p != NULL) { p->vptr = &parent_virtual_table; p->i=i; p->j=j; } return p; } int getI(Parent * parent) { struct classParent * p = (struct classParent*)parent; return p->i; } int getJ(Parent* parent) { struct classParent * p = (struct classParent*)parent; return p->j; } static int parent_virtual_add(Parent* parent ,int value) { struct classParent * p = (struct classParent*)parent; return p->i + p->j + value; } int parent_add(Parent* parent ,int value) { struct classParent * p = (struct classParent*)parent; return p->vptr->pAdd(p,value); } void parent_free(Parent* parent) { free(parent); } Child * child_creat(int i,int j ,int k) { struct classChild * ret = (struct classChild *) malloc(sizeof(struct classChild)); if(ret != NULL) { ret->p.vptr= &child_virtual_table; ret->p.i =i; ret->p.j =j; ret->k =k; } return ret; } int getK(Child * child) { struct classChild * ret =(struct classChild *)child; return ret->k; } int child_virtual_add(Child* child,int value) { struct classChild * ret =(struct classChild *)child; return ret->k + value; } int child_add(Child* child,int value) { struct classChild * ret =(struct classChild *)child; return ret->p.vptr->pAdd(ret,value); }main.c文件
#include <stdio.h> #include <stdlib.h> #include "Test.h" void howtoadd(Parent* p ,int v) { int r =parent_add(p,v); printf("r = %d\n", r); } int main() { Parent * p = parent_create(1,2); //printf("%d\n",getI(p)); Child * cp =child_creat(1,22,333); printf("%d\n",parent_add(p,3)); printf("%d\n",child_add(cp,3)); howtoadd(p,3); howtoadd(cp,3); parent_free(p); parent_free(cp); return 0; }参考一 :狄泰软件学院C++进阶剖析 参考二 : C++ primer中文版