#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"Generate a Base"<<endl;
}
virtual ~Base()
{
cout<<"Destroy a Base"<<endl;
}
virtual void reclaim()
{
cout<<"reclaim a Base"<<endl;
}
};
class Derived:public Base
{
public:
Derived():Base()
{
tmp = new int[10];
cout<<"Generate a Derived"<<endl;
}
virtual ~Derived()
{
delete []tmp;
cout<<"Destroy a Derived"<<endl;
}
virtual void reclaim()
{
cout<<"reclaim a Derived"<<endl;
}
private:
int* tmp;
};
int main()
{
{
Derived d;
Base& b = d;
b.reclaim();
}
char c_exit;
cin>>c_exit;
}
53行Base& b=d;
b与d代表同一个对象,拥有同一个虚函数表vtable。
如果改成Base b=d;
b与d不是同一个对象,而且拥有不同类型,拥有不同的虚函数表vtable。
模拟虚函数表,引用自mattew wilson <imperfect c++>;实际上vlc中,用C语言,通过类似的方法模拟了虚函数表。
//IObject.h
#include <assert.h>
# ifdef __cplusplus
extern "C"
{
#endif
struct IObjectVTable
{
void (*SetName)(struct IObject *obj, char const *s);
char const *(*GetName)(struct IObject const *obj);
};
struct IObject
{
struct IObjectVTable *const vtable;
# ifdef __cplusplus
protected:
typedef struct IObjectVTable vtable_t;
protected:
IObject(vtable_t *vt)
: vtable(vt)
{}
IObject(IObject const &, vtable_t *vt)
: vtable(vt)
{}
public:
inline void SetName(char const *s)
{
assert(NULL != vtable);
vtable->SetName(this, s);
}
inline char const *GetName() const
{
assert(NULL != vtable);
return vtable->GetName(this);
}
private:
IObject(IObject const &rhs);
IObject &operator =(IObject const &rhs);
protected:
~IObject()
{
}
# endif /* __cplusplus */
};
IObject *make_Object(char const *s);
void release_Object(IObject*& obj);
# ifdef __cplusplus
};
#endif
//ObjectServer.cpp
#include <stdio.h> #include "IObject.h" class Object1 : public IObject { public: typedef Object1 class_type; public: virtual void SetName(char const *s) { m_name = s; } virtual char const *GetName() const { return m_name; } public: Object1() : IObject(GetVTable()) {} Object1(Object1 const &rhs) : IObject(GetVTable()) , m_name(rhs.m_name) {} public: ~Object1() { } private: static void SetName_(IObject *this_, char const *s) { static_cast<class_type*>(this_)->SetName(s); } static char const *GetName_(IObject const *this_) { return static_cast<class_type const*>(this_)->GetName(); } static vtable_t *GetVTable() { static vtable_t s_vt = MakeVTable(); return &s_vt; } static vtable_t MakeVTable() { vtable_t vt = { SetName_, GetName_ }; return vt; } private: char const *m_name; }; IObject *make_Object(char const *s) { IObject *obj = new Object1(); obj->SetName(s); return obj; } void release_Object(IObject*& obj) { Object1* p_b = static_cast<Object1*>(obj); delete p_b; obj = NULL; } int main(int argc, char** argv) { char const *strings[] = { "Reginald Perrin" , "Archie Goodwin" , "Scott Tracy" }; for(int i = 0; i < 3; ++i) { printf("Calling make_Object()\n"); IObject *obj = make_Object(strings[i]); printf("%s\n", obj->GetName()); release_Object(obj); } return 0; }