查看文章 |
有时候我们需要把一段char 的buf强行转换成某个类或其数组,比如说在使用mem_tank时,就需要先调用write_null_data方法获取内存,再转换成需要的类型。
如果要转换的类定义了虚函数,则无论是直接memcpy还是类型强转后使用=赋值,都比较危险;对于这种场景,可以使用placement new来避免,示例代码如下:
#include <stdio.h> #include <string.h> #include <new>
class A { public: A() { a = 1; b = 2; }; int a; int b;
const A & operator=(const A & src) { a = src.a; b = src.b; } virtual void foo(); };
class B : public A { int c; virtual void foo(); };
void A::foo() { printf("A Hello!\n"); }
void B::foo() { printf("B Hello!\n"); }
int main(int argc, char* argv[]) { char szbuf[256]; A a;
memset(szbuf, 0, sizeof(szbuf)); A* pa = new(szbuf)A(); printf("A.a=%d, A.b=%d\n", pa->a, pa->b); pa->foo();
a.a = 3; a.b = 4; *pa = a; printf("A.a=%d, A.b=%d\n", pa->a, pa->b);
pa = new(szbuf)B(); printf("A.a=%d, A.b=%d\n", pa->a, pa->b); pa->foo();
fflush(stdout);
memset(szbuf, 0 , sizeof(szbuf)); A* pa2 = (A*)szbuf; *pa2 = a; //memcpy(pa2, &a, sizeof(pa2)); pa2->foo();
return 0; }
输出结果如下: tandai@tc-dpf-rd /home/tandai>:g++ -o new_t new_t.cpp tandai@tc-dpf-rd /home/tandai>:./new_t A.a=1, A.b=2 A Hello! A.a=3, A.b=4 A.a=1, A.b=2 B Hello! Segmentation fault (core dumped)
可以看到,使用placement new,可以正确的使用虚函数;而强转后=赋值,由于虚表指针被破坏,程序出core了。不过,使用placement new时要注意,一定得显示的调用类析构函数(防止内存泄漏),而不能调用delete(防止重复释放空间),即new和delete成对,placement new和显示析构成对. |