#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;
}