百度空间 | 百度首页 
 
查看文章
 
用placement new避免强制类型转换时虚函数表指针的破坏
2009-06-17 22:06

有时候我们需要把一段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和显示析构成对.


类别:c++ | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu