第1章 关于对象(Object Lessons)(1)
在C语言中,"数据"和"处理数据的操作(函数)"是分开来声明的,也就是说,语言本身并没有支持"数据和函数"之间的关联性。我们把这种程序方法称为程序性的(procedural),由一组"分布在各个以功能为导向的函数中"的算法所驱动,它们处理的是共同的外部数据。举个例子,如果我们声明一个struct Point3d,像这样:
- typedef struct point3d
- {
- float x;
- float y;
- float z;
- } Point3d;
欲打印一个Point3d,可能就得定义一个像这样的函数:- void
- Point3d_print( const Point3d *pd )
- {
- printf("(%g, %g, %g )", pd->x, pd->y, pd->z );
- }
或者,如果要更有效率一些,就定义一个宏: - #define Point3d_print( pd ) \
- printf("(%g, %g, %g )", pd->x, pd->y, pd->z );
抑或是直接在程序中完成其操作:- void
- my_foo()
- {
- Point3d *pd = get_a_point();
- ...
- /* 直接打印出 point ... */
- printf("(%g, %g, %g )", pd->x, pd->y, pd->z );
- }
同样的道理,某个点的特定坐标值可以直接存取:- Point3d pt;
- pt.x = 0.0;
也可以经由一个前置处理宏来完成:- #define X( p, xval ) (p.x) = (xval);
- ...
- X( pt, 0.0 );
在C++(www.cppentry.com)中,Point3d有可能采用独立的"抽象数据类型(abstract data type,ADT)"来实现: - class Point3d
- {
- public:
- Point3d( float x = 0.0, float y = 0.0, float z = 0.0 )
- : _x( x ), _y( y ), _z( z ) { }
-
- float x() { return _x; }
- float y() { return _y; }
- float z() { return _z; }
-
- void x( float xval ) { _x = xval; }
-
- // ... etc ...
- private:
- float _x;
- float _y;
- float _z;
- };
-
- inline ostream&
- operator<<( ostream &os, const Point3d &pt )
- {
- os << "(" << pt.x() << ", "
- << pt.y() << ", " << pt.z() << " )";
- };
或是以一个双层或三层的class层次结构完成:- class Point {
- public:
- Point( float x = 0.0 ) : _x( x ) { }
-
- float x() { return _x; }
- void x( float xval ) { _x = xval; }
- // ...
- protected:
- float _x;
- };
-
- class Point2d : public Point {
- public:
- Point2d( float x = 0.0, float y = 0.0 )
- : Point( x ), _y( y ) { }
-
- float y() { return _y; }
- void y( float yval ) { _y = yval; }
- // ...
- protected:
- float _y;
- };
-
- class Point3d : public Point2d {
- public:
- Point3d( float x = 0.0, float y = 0.0, float z = 0.0 )
- : Point2d( x, y ), _z( z ) { }
- float z() { return _z; }
- void z( float zval ) { _z = zval; }
- // ...
- protected:
- float _z;
- };