请教:如何讲内存池的内存块初始化给一个确定的对象,即如何对虚函数指针vptr初始化,详见内容

时间:2021-10-15 21:57:43
RT:
请教:如何讲内存池的内存块初始化给一个确定的对象,含有虚函数指针

主要如给对象的中的虚函表地址vptr初始化。
大意如下边代码

class CBase
{
public:
CBase()
{
cout << "CBase构造" << endl;
}

~CBase()
{
cout << "CBase析构" << endl;
}

void init()
{
id = 1;
}

virtual void PrintFunc()
{
cout << "virtual void PrintFunc: CBase" << endl;
}

private:
int id;
};

class CTest:public CBase
{
public:
CTest()
{
cout << "CTest构造" << endl;
}

~CTest()
{
cout << "CTest析构" << endl;
}

void init()
{
CBase::init();
m_age = 3;
}

virtual void PrintFunc()
{
cout << "virtual void PrintFunc: CTest---------" << endl;
}
private:
int m_age;
};

int main()
{
void * ArrayBase[3] = {0};
for (int i=0; i<3; i++)
{
ArrayBase[i] = (void *)new char[sizeof(CBase)];
}

cout << "sizeof(CBase)  " << sizeof(CBase) << endl;

void * Array[3] = {0};
for (int i=0; i<3; i++)
{
Array[i] = (void *)new char[sizeof(CTest)];
}

cout << "sizeof(CTest)  " << sizeof(CTest) << endl;

CBase *pObj = (CBase *)ArrayBase[0];
if ( pObj != NULL)
{
pObj->init();
pObj->PrintFunc();
}

pObj = (CBase *)Array[0];
if (pObj != NULL)
{
pObj->init();
pObj->PrintFunc();
}

return 0;
}


数据成员可以通过init函数进行初始化

但vptr如何进行初始化?
请指教

6 个解决方案

#1


vptr的初始化是编译器替我们完成的,自己不用去初始化。

#2


1 自己构造虚表,比如根据《深入探索C++对象模型》或者网上的一些资料,但是这个比较麻烦,特别是继承关系比较复杂的情况下,而且很容易出错。
2 重载new,在new里面返回内存池的内存指针,new返回后会自动调用构造函数,也会自动生成虚表。这是最方便的办法,这样既可以利用上内存池,又可以自动调用构造函数,而不用专门Init初始化,更不用自己生成虚表。

#3


引用 1 楼 guoxuqu 的回复:
vptr的初始化是编译器替我们完成的,自己不用去初始化。

那如何把内存池与对象联系起来?

就是我不直接定义一个对象,而是从内存块取一块内存,然后通过某种方式,把该内存块转化为具体的一个对象所有的内存空间
大意如代码所示

#4


引用 2 楼 visualwind 的回复:
1 自己构造虚表,比如根据《深入探索C++对象模型》或者网上的一些资料,但是这个比较麻烦,特别是继承关系比较复杂的情况下,而且很容易出错。
2 重载new,在new里面返回内存池的内存指针,new返回后会自动调用构造函数,也会自动生成虚表。这是最方便的办法,这样既可以利用上内存池,又可以自动调用构造函数,而不用专门Init初始化,更不用自己生成虚表。


对 2,
你的意思是,直接new n 个对象到出来,然后放到内存池?

#5


是重载new

全局重载:
static void *operator new(size_t nSize)
{
    return 你的内存池的指针
}

类重载(VC编译器):
class CTest:public CBase
{
#if defined _DEBUG
void *operator new(size_t nSize, const char *pszFileName=NULL, int nLineNum=0)
{
#else
void *operator new(size_t nSize)
{
#endif
    return 你的内存池的指针
}

引用 4 楼 teshumingzi 的回复:
引用 2 楼 visualwind 的回复:
1 自己构造虚表,比如根据《深入探索C++对象模型》或者网上的一些资料,但是这个比较麻烦,特别是继承关系比较复杂的情况下,而且很容易出错。
2 重载new,在new里面返回内存池的内存指针,new返回后会自动调用构造函数,也会自动生成虚表。这是最方便的办法,这样既可以利用上内存池,又可以自动调用构造函数,而不用专门Init初始化,更不用自己生成虚表……

#6


lz看来不知道重载new啊....就这种情况,还是先学好语法吧,别动不动就玩什么池了。。

#1


vptr的初始化是编译器替我们完成的,自己不用去初始化。

#2


1 自己构造虚表,比如根据《深入探索C++对象模型》或者网上的一些资料,但是这个比较麻烦,特别是继承关系比较复杂的情况下,而且很容易出错。
2 重载new,在new里面返回内存池的内存指针,new返回后会自动调用构造函数,也会自动生成虚表。这是最方便的办法,这样既可以利用上内存池,又可以自动调用构造函数,而不用专门Init初始化,更不用自己生成虚表。

#3


引用 1 楼 guoxuqu 的回复:
vptr的初始化是编译器替我们完成的,自己不用去初始化。

那如何把内存池与对象联系起来?

就是我不直接定义一个对象,而是从内存块取一块内存,然后通过某种方式,把该内存块转化为具体的一个对象所有的内存空间
大意如代码所示

#4


引用 2 楼 visualwind 的回复:
1 自己构造虚表,比如根据《深入探索C++对象模型》或者网上的一些资料,但是这个比较麻烦,特别是继承关系比较复杂的情况下,而且很容易出错。
2 重载new,在new里面返回内存池的内存指针,new返回后会自动调用构造函数,也会自动生成虚表。这是最方便的办法,这样既可以利用上内存池,又可以自动调用构造函数,而不用专门Init初始化,更不用自己生成虚表。


对 2,
你的意思是,直接new n 个对象到出来,然后放到内存池?

#5


是重载new

全局重载:
static void *operator new(size_t nSize)
{
    return 你的内存池的指针
}

类重载(VC编译器):
class CTest:public CBase
{
#if defined _DEBUG
void *operator new(size_t nSize, const char *pszFileName=NULL, int nLineNum=0)
{
#else
void *operator new(size_t nSize)
{
#endif
    return 你的内存池的指针
}

引用 4 楼 teshumingzi 的回复:
引用 2 楼 visualwind 的回复:
1 自己构造虚表,比如根据《深入探索C++对象模型》或者网上的一些资料,但是这个比较麻烦,特别是继承关系比较复杂的情况下,而且很容易出错。
2 重载new,在new里面返回内存池的内存指针,new返回后会自动调用构造函数,也会自动生成虚表。这是最方便的办法,这样既可以利用上内存池,又可以自动调用构造函数,而不用专门Init初始化,更不用自己生成虚表……

#6


lz看来不知道重载new啊....就这种情况,还是先学好语法吧,别动不动就玩什么池了。。