【面向对象】面向对象是一种思想,而不是一种编程语言
几乎任何语言都可以面向对象。汇编也可以。我认为:把不同的事物,用编程语言描述清楚,然后对它们进行组织调用,就是面向对象。并不一定非得是C++的那种形式,任何语言都可以面向对象。
面向对象并不是把数据重新用结构体进行打包,而是把事物当成对象来看待。比如“向量”,就把它看成对象,对向量进行运算的程序专门写,而不是在用到向量的地方用float来表示。比如这样:typedef struct
{
float x,y,z;
}Vector3,*Vector3P;这里定义了一个三维向量。这是对象吗?是的。而非面向对象的编程思路是什么呢?就像下面这样:float x,y,z;当然这个也可以被当成对象来编程,但是真正有说服力的是下面的代码。//代码演示:判断一个三维空间中的点是否在一个立方体的内部
//=============================================================================
//面向对象的思想
//-----------------------------------------------------------------------------
#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等各种国际开源项目的源码。 原本的面向过程编程 是向函数传递结构体指针 让一个函数可以为同一结构体的多个变量服务
面向对象只不过是编译器做了这步 本质还是面向过程 将结构体理解成对象的数据 然后偷偷的把this指针用第一个参数传给成员函数了 也就是所有成员函数其实都带有一个隐藏参数
不过面向对象的基本特征不是那么好模拟的 继承和多态 不是面向过程语言简单就能做到的
这也就是人家说的 c++ java 才能真正的面向对象了... 我晕 发表于 2014-9-3 07:33
原本的面向过程编程 是向函数传递结构体指针 让一个函数可以为同一结构体的多个变量服务
面向对象只不过是 ...
这是你对面向对象的定义吧?
个人觉得Linux的源码就是面向对象的。 0xAA55 发表于 2014-9-3 16:57
这是你对面向对象的定义吧?
个人觉得Linux的源码就是面向对象的。
呵呵 我对面向对象的定义? 这应该算业内的看法吧
好吧 那你可以说每个人的定义都不同...
Linux的源码我只在下载时翻了一下 根本没看过 不过我觉得你这句话我应该能认同 的确有很多代码 看上去立刻就有一种感觉 应该就是你说的面向对象了 额,其实我想说楼主的理解还是面向过程并没有面向对象。面向对象的最起码要具备三个特性,封装,继承和多态。就拿封装这一条来说,什么是封装?就是把数据和在数据上的操作封装起来,这就是一个对象,也就是说对象需要具有能对其自身进行操作的能力。比如在C++中定义一个struct Vector3D { float x; float y; float z;}; 假如现在要对这个向量规范化,那么可能会需要一个函数比如 void Normal(Vector3D &vec3D); 这就是早期的函数库思想,C语言中很多类似这样的库,这就是一种面向过程的思想。如果是面向对象,那么Vector3D中就应该包含对自身进行规范化的函数(我想不用多说,C++的struct是可以定义函数的),结果就是struct Vector3D {float x; float y; float z; void Normal(){函数定义} };,这样以后如果建立一个对象 Vector3D vec3D; 直接调用这个对象的函数 vec3D.Normal();就完成了规范化,这就是面向对象。当然封装的内容不仅仅这么多,继承和多态我就不说了,反正楼主所说的还是停留在面向过程阶段。 sizz 发表于 2014-11-21 14:13
额,其实我想说楼主的理解还是面向过程并没有面向对象。面向对象的最起码要具备三个特性,封装,继承和多态 ...
那就是形式上的区别喽?你让我想起了COM类这种不伦不类的东西,如果让C语言使用,这个应该算面向对象还是面向过程呢?
此外多态可以通过转换结构体指针,使用union来实现,而继承也是如此。
另外如果要C语言实现你说的那种特性,那也可以,使用一些宏即可。 这不是形式上的区别,那我们换个角度说,如果楼主你上面定义的Vector3结构体假如在某个编译器中已经被实现为一种基本类型,就和int bool float这类一样的基本类型,那么楼主帖子中两个函数实现又有什么区别呢,都是对基本类型的操作而已。其模式开始“用一个函数去操作另一个对象”,而不是“对象对自身进行操作”,这就是本质区别。 sizz 发表于 2014-11-21 14:35
这不是形式上的区别,那我们换个角度说,如果楼主你上面定义的Vector3结构体假如在某个编译器中已经被实现 ...
从汇编的角度来看,“用一个函数去操作另一个对象”和“对象对自身进行操作”是一样的。
面向对象是一种思想而不是一种编程语言。请仔细看原文。
页:
[1]