-
第一章
在
C++
中有两种
class data
members:
1
static
和
nnstatic.
○
?
三种
class member functions:
p>
1
static
、
nonstatic
和
virtual
。
○
?
表格驱动对象模型(
A
Table-
driven Object Model
)
:
?
把所有与
members
相关的住处抽出来,放在
一个
< br>data member table
和
一个
member
function table
之中,
class object
本身
则内
含指向
这两个表格的
指针
:
1
member
function table
是一系列的
slots
,
每一个
slot
指出
一个
member function;
○
2
data member abl
e
则
直接含有
data
本身。
○
?
C++
对象模型(
The C++ Object
Model
)
?
Nonstatic data
member
被置于每一个
class object
之内
,
staticdata member<
/p>
则被存放
在所有
class
object
之外
,
st
atic
和
nonstatic
function
member
也被
放在
所有的
class
object
之外
。
Virtual functi
on
则以
两个步骤
支持:
1
产生一个
virtual tabl
e(
vtbl
)
表中是一个个的函数指
针,指向
virtual
function
;
○
2
每个
class object
被
添加
一个指针,
指向
相关的
virtual table
(
vptr
)
○
。
p>
Vptr
的设定
和重置都由每一个的
class
的
constructor
、
destructor
和
< br>copy assignment
运算符自动
完成。
p>
?
需要多少内存才能表现一个
class object?
1
nonstatic data
member
的总和大小;
○
2
任何由于
alignment(
译注
)
的需求而填补
(p
adding)
上去的空间;
○
p>
3
为了支持
virtual
而由内部产生的任何额外负担
(overhead);
○
?
一个
OB
(object
base)
设计可能比一个对等的
OO
(object
oriented)
设计
速度更快而且空间
更紧凑
,
< br>速度快
是因为所有的函数引发操作都在编译时期解析完成
,
对象建构起来不需
要设置
virtu
al
机制;
空间紧凑
则是因为每一个<
/p>
class
object
不需要负担传
统上为了支持
virtual
机制而需要的额外负荷,不过
p>
OB
设计比较没有弹性。
?
一个指针或者引用之所以支持多态
,
是因为他们并不引发内存中任何
“与类型有关的内
存委托操作”
受到影响的只是
“目标内存的大小和
内容
“的解释方式。
而基类对象被初
始
化为子类对象,其子类对象的信息就会被
slice
,以塞入较
小的基类内存中,而派生
类型没有在基类对象中留下任何的信息,包括
< br>vptr
。
?
C++
程
序支持
3
种编程模型:
1
过程
model
,像
p>
c
一样
;
○
p>
2
抽象数据类型模型
(ADT)
,只有封装,没有继承和多态;
○
3
面向对旬模型
(OO)
,
典型的支持继承、封装和多态。
○
?
C++
中支持金矿的方法:子类对象基类指针、引用;虚函数;
dyn
amic_cast
或者
typeid
运算符。
第二章
(the semantics of
constructors)
?
Default
constructors
< br>在需要时被编译器产生出来(注:差别在于一个是
程序的需要
,一
个是
编译器的需要
)
。
?
Copy constructor
(如果是
< br>默认
的拷贝并不会拷贝
member class
object
)
1
< br>赋值时;○
2
传参时;○
3
p>
返回时;
○
?
把一个
class object
当做
参数传给一个函数,
相当于
以下形式初始化操作
:
1
x
xx
=
xxx;
○
?
例返回转换:
X
bar()
{
X xx;
Return xx;
}
//
可能转换为下列形式:
V
oid
bar(
x& _result
)
{
X xx;
xx.x::xx();
//
default
constructor
_result.x::xx(xx);
//
copy
constructor
Return;
}
现在编译器必须转换每一个
bar
()
调用操作,以反映其新定义。如:
X xx = bar();
将被转换为下列两个指令句:
X
xx;
Bar(xx);
而
bar
().memfunc()
可能被转化为:
X _temp0;
(bar(_temp0),_temp0).memfunc();
同样道理,如果程序声明了一个
函数指针
,像这样:<
/p>
X (*pf)();
Pf =
bar;
它也必须被转化为
:
V
oid (*pf)(x&);
Pf = bar;
第三章
(The
semantics of daa)
?
Static data
members
存放在程序的
data
segment
中和个别的
class
object
无关。
?
相邻
me
mber
之间未必连续。
?
类中处于同一个
access
section
中的数据,必定保证以其声明次序出现在内存
布局中。
但是不同的
access
section
中的各个数据,其排列次序则没有规定。
?
Member
的位置在编译时就固定了,因此存取
members
只是一
个简单的
offset
运算。
?
取一个
nonstatic data member
的地址,将会得到它在
class
中的
offset
,
取一个
“绑定于
真正
class
object
身上的
data member
< br>”的地址,将会得到该
member
在内存中的
真正
地
址。
?
如:
&c
.x
所得结果减
x
的偏移值,并加
p>
1
,就会得到
c
起
始地址。
第四章
(The semantics of
function)
?
如果
fun()
是一个
virtual
member function
,那么以下的调用:
?
ptr->fun();
将会被内部
转化为
:
?
(*ptr->vptr[1])(ptr);
?
如果取一个
static member
function
的地址,获得的将是其在内存中的位置,也就是其地
-
-
-
-
-
-
-
-
-
上一篇:C#中类的定义
下一篇:SAS中的聚类分析方法总结