个人感觉c和c++最大的不同就是c++的编译器更勤快,为我们作了更多的工作。比如计算偏移以及在对象生命周期结束时添加相应析构函数的调用。
如下面简单的c++代码
代码:
#include <stdio.h> class CBase { public: CBase(): m_nTest(0) { printf( "CBase constructor.\n" ); } virtual ~CBase() { printf( "CBase destructor.\n" ); } void Test() { printf( "CBase::Test m_nTest=%d\n", m_nTest ); } virtual void VirtualTest() { printf( "CBase::VirtualTest\n" ); } protected: int m_nTest; }; class CDerived : public CBase { public: CDerived(): m_nTest(1) { printf( "CDirived constructor\n" ); } virtual ~CDerived() { printf( "CDerived destructor\n" ); } void Test() { printf( "CDerived::Test m_nTest=%d ; CBase::m_nTest=%d\n", m_nTest, CBase::m_nTest ); } virtual void VirtualTest() { printf( "CDerived::VirtualTest\n" ); } private: int m_nTest; }; int main() { CDerived derive; CBase *pbase = &derive; pbase->VirtualTest(); pbase->Test(); derive.Test(); return 0; }
C++作为面向对象语言而言,肯定具有标准的三大特性: 封装, 继承, 多态
封装: 对于C++ 而言,无非是使用类似private关键字来约束对其成员的访问权限, 不过这些约束都是在语法层面的,这些关键字不会对目标代码产生影响(同样的还有const)。
通过成员函数来进行操作可以隐藏类的信息, 这些之所以能实现是因为c++编译器太称职了,他为我们作了很多工作。
这个适用C语言无法模拟的
继承: C从某种意义上也有能做到这种特性
多态: 重载 -- 因为C++ 编译器会为每个函数改名,所以C是望尘莫及了
重写 -- C++是通过虚函数表存储对应寒暑指针的方式实现,所以C可以模拟
缺省参数一样,编译器会为帮你将没写得按声明定义补上(注意参数可是静态绑定的哦)
综上,我们可以用C来模拟c++的继承和多态特性(在单继承的情况下),当然,多继承肯定也能,毕竟两种方式只是思想上区别,声称的可执行文件指令都是一样的。
下面简单用c模拟上面的c++功能。
代码:
#include "stdio.h" typedef struct base { void** pvf; //虚函数表 int m_nTest; } CBase; void* pvfbase[2]; void* pvfderived[2]; typedef void (*pf)(CBase*); /*virtual*/ void CBaseDestructor( CBase* this ) { this->m_nTest = 0; printf( "CBaseDestructor. \n" ); } /*virtual*/ void CBaseTest(CBase* this) { this->pvf = pvfbase; //this->m_nTest = 1; printf( "CBase::Test. %d\n", this->m_nTest ); } void initbasevftbl() { pf vf = (pf)CBaseDestructor; pvfbase[0] = (void*)vf; vf = (pf)CBaseTest; pvfbase[1] = (void*)vf; } void CBaseConstructor( CBase* this ) { this->m_nTest = 1; this->pvf = pvfbase; printf( "CBaseConstructor. \n" ); } typedef struct derived { CBase base; int m_nTest; }CDerived; /*virtual*/void CDerivedDestructor(CDerived* this) { this->m_nTest = 0; //destroy self first printf( "CDerivedDestructor.\n" ); CBaseDestructor((CBase*) this); } /*virtual*/void CDerivedTest(CDerived* this) { printf( "CDerivedTest m_nTest=%d; CBase::m_nTest=%d\n", this->m_nTest, this->base.m_nTest ); } void CDerivedConstructor(CDerived* this) { CBaseConstructor((CBase*) this); this->base.pvf = pvfderived; this->m_nTest = 2; printf( "CDerivedConstructor\n" ); } void initDerivedvftbl() { pf vf = (pf)CDerivedDestructor; pvfderived[0] = (void*)vf; vf = (pf)CDerivedTest; pvfderived[1] = (void*)vf; } int main() { CBase* pbase; CDerived derive; pf pvf = NULL; initbasevftbl(); //这个过程在c++中是先于main() 函数调用的 initDerivedvftbl(); //同上 CDerivedConstructor(&derive); //C++:首先获得derive的内存空间,然后调用构造函数 pbase = (CBase*)&derive; pvf = pbase->pvf[1]; (*pvf)(pbase); //pbase->Test(); pvf = pbase->pvf[0]; (*pvf)(pbase); // c++中,这个函数是自动调用的。 return 0; }
结果:
谢谢