allocate()是Heap的成员函数,this是Heap实例的指针,这个指针指向堆还是栈根据它的实例是怎么创建的的来决定的(new出来的实例指针就在堆上,Heap t;这样直接声明的变量,则再栈上)。this指向该Heap实例的内存地址,this+1指向了该实例地址的下一个地址,因为allocate()得到的这个地址不是通过new或者变量申请得到的,它指向的内存块容易被别的变量占用。void *是无类型指针,可以强制转换成任何类型的指针。
你下面的代码,语法错误不少,先不管代码语法的问题,先说代码的理解。
Heap h;声明了一个Heap变量,h位于栈上,所以,再allocate()的时候,this就位于栈上。h.allocate()返回的是栈空间上h实例后的地址。
A* a = (A*)h.allocate()这一句也就相当于,声明了一个A类型的指针a,然后让a指向了h实例后的栈内存,所以,这段代码的实际作用就是:
将h实例后的栈内存分配给了一个变量(暂时称呼它为t),void类型没有类型指向性,所以allocate()返回的实际就是h实例后的内存首地址,然后通过(A *)进行强制转换,也就相当于把h实例后的sizeof(A)大小的栈空间分配给了变量t,最后,让a指向了这个变量。所以,后面的a->pp()就相当于:
A t;
t.pp();
同理,下面的b也是一样的。因为这块内存是栈上的,随时可以被回收和分配给其它变量。allocate()的作用仅仅是在给变量分配空间的时候,把变量的空间强制限定在了紧跟h实例后面的内存块上。这在内存空间受限的应用开发中是有价值的。
下面是修改后的代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A {
public:
void pp() {
cout << "A" << endl;
}
};
class B {
public:
void pp() {
cout << "B" << endl;
}
};
class Heap {
public:
void* allocate() const {
return (void*)(this + 1);
}
};
int main() {
Heap h;
A* a = (A*)h.allocate();
a->pp();
B* b = (B*)h.allocate();
b->pp();
}