首页 > 解决方案 > 放置新的析构函数

问题描述

当它退出范围时,是否有一种模式可以自动调用堆栈上的放置新初始化对象的析构函数?我想跳过记住显式调用析构函数的需要。或者,是否有与placement-new不同的方法来构造具有可变大小data[] 尾部的基于堆栈的对象?我使用 g++。

/* g++ f.cpp -o f.exe */
/* 8< --- f.cpp ----  */
#include <stdio.h>
#include <stdlib.h> 
#include <string>
class aclass {
public:
    aclass(int size) : size_(size) {};
    ~aclass() { /* do something */ };
    int size_;
    char data[0];
};

void f(int size)
{
    char v[sizeof(aclass) + size];
    aclass *p = new(static_cast<void*>(&v)) aclass(size);
    p->~aclass();
}

int main(int argc, char **argv)
{
    f(10);
    f(100);
    return 0;
}

标签: c++gccg++destructorplacement-new

解决方案


您可以像这样创建一个包装类:

template <typename T>
class Foo {
    private:
        T *m_ptr;
    public:
        Foo(void *area, int size) {
            m_ptr = new(area) T(size);
        }
        Foo(const Foo &) = delete;
        ~Foo() {
            m_ptr->~T();
        }

        void operator=(const Foo &) = delete;

        T *operator->() {
            return m_ptr;
        }
};

用法:

void f(int size) {
    char v[sizeof(aclass)+size];
    Foo<aclass> p(v, size);

    p->doSomething(); // call a function from aclass
}

请注意,您使用的是 GCC 扩展,因为size它不是编译时常量。

如果它是一个编译时常量,那么你可以放入vFoo并且size将是一个模板参数),这样f会更简单。


推荐阅读