C++ - 对象模型之 成员函数调用
来源:互联网 发布:金融工程硕士就业 知乎 编辑:程序博客网 时间:2024/05/16 16:58
C++对象模型目录
C++ - 对象模型之 编译器何时才会自行添加构造函数
C++ - 对象模型之 内存布局
C++ - 对象模型之 成员函数调用
C++ - 对象模型之 构造和析构函数都干了什么
C++ - 对象模型之 类对象在执行时是如何生成的
C++ - 对象模型之 模板、异常、RTTI的实现
C++ - 对象模型之 成员函数调用
C++ 类的函数共有三种,
nonestatic member function:如果调用该函数,必须实例化一个对象,然后通过对象调用,那么调用的函数处理的就是该对象。
static member function:该函数不属于任何一个对象,即使没有对象也能够调用该函数。virtual member function:多态,根据继承关系来确定对象具体调用哪个类的函数。
nonestatic member function
public:
void func1(){}
};
func1(&c1);
static member function
该类型函数和nonestatic member function函数区别在于它的参数不会带有this指针,它和普通的C函数一样,可以直接调用。由于这个特点,所以它有以下特点和用途:
1. 不能直接调用和处理nonestatic member data,因为data属于具体的某个对象,static函数无法获得对象的指针,所以无法获得该对象的data;
2. 不能使const、virtual,因为const是保护member data,既然static函数无法直接调用member data,所以没有必要声明为const,另外不管怎么继承,static函数无法获得继承后对象,所以更谈不上virtual;
3. 由于和C的函数基本一样,所以可以作为回调函数;
virtual member function
对于单一继承、多重继承、虚拟继承下的virtual function调用是有区别的,所以,我们分类说明,在说明这些问题的时候,要和《C++ - 对象模型之 内存布局》的案例对照说明。
单一继承机制
如《C++ - 对象模型之 内存布局》的“单一继承&多态”部分的代码,里面三个类GrandFather、Father、Child的vtbl布局如下
GrandFather:
|GrandFather::who()|
|GrandFather::fishing()|
|GrandFather::hungry()|
Father:
|Father::who()|
|GrandFather::fishing()|
|Father::hungry()|
|Father::cutting()|
Child:
|Child::who()|
|GrandFather::fishing()|
|Child::hungry()|
|Father::cutting()|
|Child::studying()|
1. 一个class不管有多少实例,这些实例可以共用一个vtbl,因为同类型的class的vtbl布局是一样的;
2. 为了在编译器,就能够确定virtual function对应的slot索引值,所以virtual function的排列顺序是先遍历base class,然后再遍历derived class,并且,一个virtual function不会被索引两次;
3. 每个class 实例有自己的vptr,该vptr指向vtbl;
多重继承机制
如《C++ - 对象模型之 内存布局》的“多重继承&多态”部分的代码,里面五个类GrandFather、Father、Grandad、Mother、Child的vtbl布局如下
GrandFather:
|GrandFather::who()|
|GrandFather::fishing()|
|GrandFather::hungry()|
Father:
|Father::who()|
|GrandFather::fishing()|
|Father::hungry()|
|Father::cutting()|
Grandad:
|Grandad::who()|
|GrandFather::chessing()|
|GrandFather::hungry()|
Mother:
|Mother::who()|
|GrandFather::chessing()|
|Mother::hungry()|
|Mother::sewing()|
Child:
vptr1:
|Child::who()|
|GrandFather::fishing()|
|Child::hungry()|
|Father::cutting()|
|Child::studying()|
vptr2:
|Child::who()|
|GrandFather::chessing()|
|Child::hungry()|
|Mother::sewing()|
我们得到如下的结论:1. Child有两个vptr,一个指向第一个base,一个指向第二个base,有多少base,就有多少vptrs;
2. Child的studying()函数只在第一个vptr中有索引,这样可以节省空间,这也就引出了第一个base是主要实体,后继的base都是次要实体;
3. 如果用Child指针或Father指针或GrandFather指针处理Child,包括析构,都没有区别,因为这个时候指针真正指向的Child Object的起始地址;
4. 如果用Mother指针或者Grandad指针处理Child,就必须调整this指针了。
如Mother * m = &child;
m的地址其实是&child+sizeof(Father),一般的处理也不会有什么大的问题,但是当出现delete m时,必须将调整m地址指向child的起始地址,但是这个时候,如何才能知道m实际指向的是Mother实例还是Child实例呢。
- C++ - 对象模型之 成员函数调用
- C++对象模型的那些事儿之六:成员函数调用方式
- C++类对象内存模型与成员函数调用分析
- C++类对象内存模型与成员函数调用分析
- 【C++】深度探索C++对象模型之虚拟成员函数(virtual member function)
- C++之const对象只能调用const成员函数---补充(18)《More Effective C++》
- C++对象模型之函数成员(1)
- C++对象模型之函数成员(2)
- C++对象模型之函数成员(3)
- C++对象模型之函数成员(4)
- C++对象模型之函数成员(5)
- C++对象模型之成员函数的指针
- 深度探索C++对象模型之:成员函数语义学--静态成员函数
- JNI之c调用java的函数,调用java的构造生成对象,得到java的成员,以及C返回Java字符串乱码
- C++类对象内存模型与成员函数调用分析(上)
- C++类对象内存模型与成员函数调用分析(中)
- C++类对象内存模型与成员函数调用分析(下)
- C++类对象内存模型与成员函数调用分析(上)
- S3C6410 裸机DMA
- html 锚点的使用
- 整理基础的CentOS常用命令
- CI框架基本配置/教你学习CI框架codelgniter
- jquery制作选项卡
- C++ - 对象模型之 成员函数调用
- php操作XML
- Python IDLE快捷键
- 推荐给开发人员的实用命令行工具
- 在阿里云的云服务器上:Linux服务器安装-Apache/nginx+mysql+PHP
- HashMap、Hashtable、LinkedHashMap、和TreeMap介绍和区别
- 为什么苹果三星将主宰智能电视未来?
- ScrollView
- 15款有趣的诺基亚概念手机回顾