C++对象模型-笔记一

来源:互联网 发布:知乎怎么匿名提问 编辑:程序博客网 时间:2024/05/20 11:21
关于对象:
C-Struct,一个数据的封装体,不包含数据操作,不包含读取权限
C-Class,简单的ADT模型,基于继承的对象模型,基于模版的对象模型
封装后的布局成本:
C+=在布局以及存取时间上的主要额外负担是由virtual引起的(virtual function机制和virtual base class)
继承..


C++对象模式
对象成员数据的分类(data:static,nonstatic || functions:static,nonstatic,virtual)
三种对象模型的对比
1.简单对象模型:一个object是一系列的slots(指针),每个slot指向一个member
members本身不存放在object中,只有指向member的指针
这个模型被实际应用到"指向成员的指针"观念之中
优点:修改对象成员不需要重新编译
缺点:付出额外的空间代价和存取时间代价


2.表格驱动对象模型:将成员分为数据和函数,存放于两个table中,object保存两个指向表格的指针
实际应用到了"virtual functions"中


3.实际C++对象模型:只有nonstatic data被直接存放到object中,static data和static,nonstatic function被存放到object
之外。
virtual functions的存放:每个class产生一堆指向VF的指针置于表格中:vtbl
object存放一个指针vptr,指向vtbl.
type_info object存放在vtbl第一个slot处
优点:在空间存储和时间存取的效率达到最佳效果
缺点:对于nonstatic data的修改会导致代码重新编译


对象的差异:
C++支持的三种程序设计典范: 1、程序模型,类似C的编程模式,直接操作内存
  2、ADT抽象数据类型模式:单一类型的类提供一系列接口进行编程(只有抽象)
  3、OO面向对象模型:抽象+继承(多态)


C++以下列方法支持多态:(运行时多态,有一个共同接口)
1、只有通过ptr或者ref的间接处理,才支持OO程序设计中的多态性质,否则就调用复制构造进行切割
例子: Book:Lib_material
Lib_material obj1; 
Book book; 
obj1 = book; obj1.checkIn()---->(NO,调用Lib_material:checkIn())
Lib_material &obj2 = book;(YES,Book:checkIn())


2、经由virtual function机制
3、经由dynamic_cast和typeid运算符


指针可以通过类型确定类的大小,所以能定位到子类的重写函数


指针大小,指针类型,转型:
1、指针大小都一样,
2、指针类型能够使指针确定自己的内存地址跨度
3、不改变指针地址,而是被指出指针的内存大小和内容




Bear b("Yogi");
Bear *pb = &b;
Bear &rp = *pb;


b,pb,rb的内存需求
p和r都只需要一个字节的空间(32位机器是4byte,64位机器是8byte)
而Bear Object需要24byte


一。默认构造函数
1.有类成员的类的默认构造函数
一个class没有定义构造函数的时候,在使用的时候,编译器会生成调用一个默认构造函数
编译器需要和程序员需要
一个带有多个class member objects,程序员自己定义构造函数的时候,编译器会根据member的声明次序来调用各个ctor
2.派生类的默认构造函数
没有带默认构造函数的时候,合成一个构造函数,调用上一层基类的默认构造函数


3.带有一个Virtual Function 的Class
classs声明了virtual function ,class继承一个或者多个virtual base Class 
默认构造函数会为基类和每一个派生类生成vtbl并存放该table的vptr
4.带有一个Virtual Base Class的Class
....迷迷糊糊


在合成的默认构造函数中,只有基类和类成员会被初始化,其他的非静态数据成员不会被初始化
C++新手两个常见误解:
1、任何class如果没有定义默认构造函数,就会被合成一个出来
2、编译器合成出来的默认构造函数会明确设定类中每个成员的默认值


二。复制构造函数
使用的三种情况:
1.明确以一个object的内容作为另一个class object的初值
2.当object被当作参数交给某个函数时
3.当函数传回一个class object时


默认复制构造函数:拷贝每一个内建和派生的成员数据,不会直接拷贝类成员,而是递归调用其中的复制构造函数
0 0