- UID
- 1
- 精华
- 积分
- 76361
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
几乎任何语言都可以面向对象。汇编也可以。
我认为:把不同的事物,用编程语言描述清楚,然后对它们进行组织调用,就是面向对象。并不一定非得是C++的那种形式,任何语言都可以面向对象。
面向对象并不是把数据重新用结构体进行打包,而是把事物当成对象来看待。比如“向量”,就把它看成对象,对向量进行运算的程序专门写,而不是在用到向量的地方用float来表示。比如这样:- typedef struct
- {
- float x,y,z;
- }Vector3,*Vector3P;
复制代码 这里定义了一个三维向量。这是对象吗?是的。而非面向对象的编程思路是什么呢?就像下面这样:当然这个也可以被当成对象来编程,但是真正有说服力的是下面的代码。- //代码演示:判断一个三维空间中的点是否在一个立方体的内部
- //=============================================================================
- //面向对象的思想
- //-----------------------------------------------------------------------------
- #include<math.h>
- #include<memory.h>
- //三维向量
- typedef struct
- {
- float x,y,z;
- }Vector3,*Vector3P
- //四维向量
- typedef struct
- {
- float x,y,z,w;
- }Vector4,*Vector4P;
- //三阶矩阵
- typedef struct//矩阵可以当成“坐标系”来看待
- {
- Vector3 xAxis;
- Vector3 yAxis;
- Vector3 zAxis;
- }Matrix3x3,*Matrix3x3P;
- //立方体
- typedef struct
- {
- Vector3 vSize;//长宽高
- Matrix3x3 mRotation;//旋转
- Vector3 vPosition;//位置
- }Box3,*Box3P;
- //向量乘三阶矩阵的函数
- void Vec3MulTransposedMatrix3x3(Vector3P pVOut,Vector3P pVIn,Matrix3x3P pMatrix);
- //=====================================
- //判断点是否在立方体内部的函数
- //是返回非零,否返回零
- //-------------------------------------
- int IsPointInBox
- (
- Vector3P pPoint, //点
- Box3P pBox //立方体
- )
- {
- Vector3 vTransformed;
-
- vTransformed.x=pPoint->x-pBox->vPosition.x;//相对坐标
- vTransformed.y=pPoint->y-pBox->vPosition.y;
- vTransformed.z=pPoint->z-pBox->vPosition.z;
-
- Vec3MulTransposedMatrix3x3(&vTransformed,&vTransformed,&(pBox->mRotation));//变换坐标位置
-
- if( fabs(vTransformed.x)<=pBox->vSize.x &&//如果经过变换的顶点在立方体内部
- fabs(vTransformed.y)<=pBox->vSize.y &&
- fabs(vTransformed.z)<=pBox->vSize.z)
- return 1;//返回非零
- else
- return 0;
- }
- //顶点乘三阶矩阵的函数
- void Vec3MulTransposedMatrix3x3(Vector3P pVOut,Vector3P pVIn,Matrix3x3P pMatrix)
- {
- Vector3 vTemp=
- {
- pVIn->x*pMatrix->xAxis.x+pVIn->y*pMatrix->xAxis.y+pVIn->z*pMatrix->xAxis.z,
- pVIn->x*pMatrix->yAxis.x+pVIn->y*pMatrix->yAxis.y+pVIn->z*pMatrix->yAxis.z,
- pVIn->x*pMatrix->zAxis.x+pVIn->y*pMatrix->zAxis.y+pVIn->z*pMatrix->zAxis.z
- };
- memcpy(pVOut,&vTemp,sizeof(Vector3));
- }
- //=============================================================================
- //面向过程的思想
- //-----------------------------------------------------------------------------
- #include<math.h>
- #include<memory.h>
- //=====================================
- //判断点是否在立方体内部的函数
- //是返回非零,否返回零
- //-------------------------------------
- int IsPointInBox
- (
- float px, //点
- float py,
- float pz,
- float bx, //立方体位置
- float by,
- float bz,
- float mxx, //立方体旋转矩阵
- float mxy,
- float mxz,
- float myx,
- float myy,
- float myz,
- float mzx,
- float mzy,
- float mzz,
- float sizex, //立方体尺寸
- float sizey,
- float sizez
- )
- {
- float tpx,tpy,tpz;//变换后的点
-
- px-=bx;//点相对立方体中心位置的点
- py-=by;
- pz-=bz;
-
- tpx=px*mxx+py*mxy+pz*mxz;//取得点实际相对立方体位置的点
- tpy=px*myx+py*myy+pz*myz;
- tpz=px*mzx+py*mzy+pz*mzz;
-
- if( fabs(tpx)<=sizex &&//如果经过变换的顶点在立方体内部
- fabs(tpy)<=sizey &&
- fabs(tpz)<=sizez)
- return 1;//返回非零
- else
- return 0;
- }
复制代码 面向对象并不仅仅是将数据打包做成结构体给函数使用,关键是,我们把三维向量,用Vector3来表示,而不是用float x,y,z;来表示。我们把它看作是三维向量,并针对它进行编程。这才是面向对象的思想。
面向对象的好处是代码的可复用性高,可读性高,便于管理,你看上面的矩阵、向量的结构体和辅助函数等就可以拿去别的地方使用。而面向过程的要复用就麻烦多了。
实际上汇编也可以面向对象。。事实上绝大多数语言都可以面向对象。
这个时候可能会有人提出异议:假设我有个使向量单位化的函数Normalize,我定义void Normalize(Vector3*pVec);和我定义Vector3::Normalize();是有本质区别的,因为前者是调用别的函数来完成向量单位化,而后者是向量自己把自己单位化了。前者仍然是面向过程的思想,而后者才是真正的面向对象。
对此,我认为这只是一个形式上的区别。最终编译到二进制的时候,这两者的实现方式大同小异。
那么从语义上呢?
void Normalize(Vector3*pVec);确实是调用别的函数来完成向量单位化,有“面向过程”的嫌疑,但是反过来想,对于C语言,这样已经是最接近“面向对象”思想的写法了。
比起C++,C语言的优势很多。兼容性好,可移植性好,透明度高,都是它的优势。
有关C语言面向对象的实际应用,请大家参看libpng、libjpeg、giflib、libmp3、libFLAC、zlib、7z、lzma、freetype等各种国际开源项目的源码。 |
|