a tour of c++
what is c++
bj本人给出的解释是
--a better c
--support data abstraciton
--support oop
--support gp
/*以往的编程范式*/
数据抽象是为了让用户定义类型像内部类型一样定义和使用
Decide which types you want;
provide a full set of operations for each type.
通过声明一个类实现了用户定义类型,包括构造函数,析构函数,可以让用户定义类型的定义和使用与内部定义类型相同
当从假类型转换为一个用户定义类型的时候一个特性丢失了,就是没有把表达与用户接口完全隔离开来
class Stack {
char *v;
int top;
int max_size;
public:
class Underflow { }; // used as exception
class Overflow { }; // used as exception
class Bad_size { }; // used as exception
Stack (ints); // constructor
~Stack() ; / / destructor
void push (char c);
char pop ();
};
如bj所说,stack的具体实现依赖于它的私有成员,而对于他们的访问只能通过内部的成员函数,也就是说当用户需要做一些改变的时候,必须修改class stack,重新编译。这是让用户定义数据类型像内部类型一样工作的代价。
如果我们需要把一个类型的修改与实现完全隔离,就需要用到virtual等语法
class Stack {
public :
class Underflow { }; // used as exception
class Overflow { }; // used as exception
virtual void push (char c ) = 0 ;
virtual char pop () = 0 ;
};
以上的interface可以作为任何提供了以上两个虚函数的具体实现的类的interface,也就是说任意形式的stack都可以从以上继承而来
push()pop()的实现由stack的子类来实现,这样的机制同时也支持了c++的多态性,这种多态性也就是 一种接口,多种实现。
可以通过 基类的指针或者引用 的类型来调用子类中不同版本的虚函数
例子:
#include <iostream.h>
class point //屏幕上的点类
{int x,y;
public;
point(int x1,int y1)
{x=x1;y=y1;}
virtual void showarea()
{cout<<″Area of point is:″<<0.0<<endl;}
};
class circle:public point//圆类
{int radius;
public:
circle(int x,int y,int r):point(x,y){ radius=r;}
void showarea(){cout<<″Area of circle is:″<<3.14
*radius*radius<<endl;}
};
void disparea(const point*p) //多态程序段
{p->showarea();}
void main()
{circle c1(1,1,1);disparea(&c1);
}
这里的正确的结果是Area of circle is:1
那么如何分辨不同虚函数版本的调用呢,一种实现方法就是vtbl,为每个派生类加上一个vtbl指针,这样做会产生相应的额外开销。
OOP
这里更像是对前面的总结,其中描述的在前面的小节中基本都已经出现
类继承的机制以及以上就提出了oop的编程范式
Decide which classes you want;
provide a full set of operations for each class;
make commonality explicit by using inheritance.
确定你需要的类,为每个类提供一组操作,用继承明确得表示共性
当然并不是所有的项目都需要找出一组共性才是最优的方案
GP
泛式
包括数据类型和算法,基本理念与上面相同,将实现与用户使用和类型隔离,利用template等语法
其代表就是STL的容器以及算法
一种语言不可能是完美的,如果对于某个项目支持完美,那么对于另外一个必然是有欠缺的,而C++被设计用于广泛应用。