您的位置:首页 > 编程语言 > C语言/C++

深度搜索C++对象模型 - 关于对象

2014-09-21 09:20 183 查看

深度搜索C++对象模型:

关于对象:

在C语言中 数据 和 处理数据的操作(函数) 是分开来声明的 也就是说 语言本身并没有支持"数据和函数"之间的关联性;

我们把这种程序方法成为 程序性的; 有一组"分布在各个以功能为导向的函数中"的算法所驱动, 他们处理的是共同的外部数据;

而C++则会考虑使用一种独立的 抽象数据类型 ADT 来实现一些数据和函数的关联性;
( 其实就是class )

类对于函数和数据来说 加上了封装; 对于加上封装必然会带来一些布局成本;

但是对于C++来说 布局以及存取时间上的主要的额外负担是 virtual 引起的 ( 包括 virtual function 机制, virtual base class 机制 )

C++对象模式:

C++有两种 class data members :     static 和 nostatic

C++有三种 class member function : static 和 nostatic 和 virtual

例如:

而对于class Point在机器内存中会表现成什么样 ?

class Point
{
public:
static int m_Num;			// static data member;
int m_Age;				// nostatic data member;
static void Func1();			// static member function;
void Func2();				// nostatic member function;
virtual Func3();			// virtual member function;
};


-->  简单对象模型 :

这个模型中 一个 class object 是一系列的slots 每一个slot指向一个members; ( 可能是data member 也可能是 member function )

-->  表格驱动的对象模型 :

这个模型中 所有与member相关的信息被分类并抽取出来 放到一个 data member table 和一个 member function table 中;

class object 本身则是指向这两个表格的指针; data member table 内涵data数据; 而 member function table中是一系列的slot 指向了member function;
-->  C++对象模型 :

此模型中 class object 中配置了 nostatic data member; 然后还配置了一根指向 virtual table 的指针;

对于 static data member, nostatic member function, static member function 则被配置到了 class object 之外;

 C++程序设计范式 :

-->  程序模型 :

类似于C语言的 顺序化的程序设计思路;
-->  抽象数据类型模型( ADT )  :

类似于C++提供的 string 类;
-->  面向对象模型( OO ) :

此模型中有一些彼此相关的类型, 通过一个抽象的base class 封装起来 ( 其实就是class设计 );

虽然我们可以间接或直接的处理集成体系中的一个 base class object, 但是只有通过 pointer 或 reference 的间接处理

才支持OO程序设计所需的多态性质;
在OO设计范式中, 我们需要处理一个未知实例, 他的类型虽然有所界定,却有无穷可能;

这组类型受制于其继承的体系, 这个体系没有深度和广度的限制;

原则上, 被指定的object的真是类型在每一个特定执行点执行之前, 是无法解析的,

在C++中, 只有通过 pointer 和 reference 的操作才能够完成, ( 通过pointer来指代无法预知的类型 );

而在ADT范式中 所有的实例都是固定而且单一的, 他在编译的时候已经完全定义好了;

虽然 对于object的多台操作 要求此object必须可以经由一个pointer或者reference来存取,

但pointer或reference的处理却不是多态处理的必然结果;

( 对于一个 int * 类型的指针 他就没有多态的处理 )

结论: C++中 多态只存在于一个个的public class 体系中( 必须是 public 继承 );

C++提供三种方式支持多态:

-->  有一组隐式的转化操作 :

shape *ps = new circle();
-->  经由 virtual function 机制 :

ps->rotate();
-->  经由 dynamic_cast 和 typeid 运算符 :

if( circle *pc = dynamic_cast< circle * >( ps ) )...

多态的主要用途是经由一个共同的接口来影响类型的封装, 这个接口通常被定义在一个抽象的base class中;

这个共享接口是以 virtual function 机制引发的,他可以在执行期间根据object的真正类型解析出到底是哪一个函数实例被调用;

 一个类需要多少内存大小

--> 其 nonstatic data members 的总和大小

--> 加上任何由于内存对其要求填补的内存空间

--> 加上为了支持virtual function机制而在内部产生的额外负担( 一般是一根vptr )

 指针的类型

ZooAnimal *px;

int *pi;

Array< String > *pta;
以上三根指针有何不同?

从内存需求的观点来说  没什么不同 ,

他们三个都需要足够的空间来放置一个机器地址( 通常是一个dword, 4字节 );

 指向不同类型的指针 之间的差异, 即不再其指针表示法不同,也不再其内容( 一个地址 )不同 ;

而是在于 其所寻址出来的object类型不同 ,也就是说 指针类型会教导编译器如何解释特定地址中的内存及其大小 ;

( 例如 一个int *p;指针, 他将会覆盖4字节的内存地址 假设p内容为( 1000H ), 那么他将会覆盖 1000H - 1003H )

( 那么 如果是一根 double *p 指针, 他自然会覆盖8字节的内存地址, 因为他是double类型的指针 )

( 但是对于两根指针本身来说 他们没有任何区别 都是一个双字 里面存的是4字节的地址 )
那么来解释一下: ( ZooAnimal是父类 Bear是子类 )

Bear *be = new Bear();

ZooAnimal *za = be;
他们有何区别:

就这两根指针来说 他们没有任何区别, 如果你这么写 za == be; 那么他会是真

为什么 因为这个值比较的是两根指针的内容 根据我们上面所说 他俩都指向了同一个new Bear(); ( 堆地址 );

指向了同一个东西 所以他们的内容  也就是new Bear()的地址  完全相同 所以上面的判断会返回真;

但是他俩又是不一样的, 因为 be是Bear类型的指针, 但是an是ZooAnimal类型的指针

be指针是Bear类型 他会教导编译器按照Bear的内存模型解释 ( 父类内存模型 + 子类内存模型 )

an指针是ZooAnimal类型 他会教导编译器按照ZooAnimal的内存模型解释( 只有父类内存模型 )

所以他们的表现是不相同的,,, 虽然be == an;
za = be; 这句话唯一影响到的只有 za指向内存的大小和内容解释方式 而已

be = za; 这样则不允许, 因为这样做会 溢出他所配置得到的内存 ;
C++通过class的pointer和reference来支持多态, 这种程序设计风格就是 面向对象 ;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 对象 语言 多态