void* allocate() const {
return (void*)(this + 1);
}
这个函数的返回值,可以转换成一切类型的对象。可以说可以直接分配任何类型对象的内存。但是我对这个this+1确实不理解,我在往上查到this+1指向当前对象的最后一个内存地址,但是他怎么就替代了new了?这样分配内存的对象,是属于栈还是属于堆?
完整代码:
class A {
public:
void pp() {
cout<<"A"<class B {
public:
void pp() {
cout<<"A"<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();
}
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();
}
首先说下我的结论,这里并没有代替new,也没有分配任何内存对象,只是正好这些函数都是没有副作用的还是,所以不会对系统造成破坏。
非要说是在栈上还是堆上的话,那只能说是在栈上,但是在未分配的位置,或者已分配但属于其他对象的位置,总之是非法的(但是编译器不检测)位置,强行分配的。当然,如果h是通过new得来的,就是在堆上了。
将任何东西强制转换成A类型都可以这样操作,详见下面的测试代码。
你的需要修改一下才能运行:
1、补上class定义的分号;
2、成员访问运算符->和.的使用好像也有问题;
当然我不清楚这是不是你的本意,修改后如下
#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();
int i = 0;
A* a2 = (A*)i;
a2->pp();
B* b2 = (B*)&h;
b2->pp();
}
没那么必要复杂:
你的main 代码写错了,h 只是个对象,不是指针,不要用 ->
allocate() 只是获得一个地址,并不是new 的替代,因为 new 需要完成的过程,对象要构造,内存要映射,而你这个只是获得了一个内存的虚拟地址,别的什么也没做;
望采纳
《深度探索C++对象模型》
《C++反汇编与逆向分析技术揭秘》