c++ - 放置新的析构函数
问题描述
当它退出范围时,是否有一种模式可以自动调用堆栈上的放置新初始化对象的析构函数?我想跳过记住显式调用析构函数的需要。或者,是否有与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;
}
解决方案
您可以像这样创建一个包装类:
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
它不是编译时常量。
如果它是一个编译时常量,那么你可以放入v
(Foo
并且size
将是一个模板参数),这样f
会更简单。
推荐阅读
- android-emulator - 互联网不适用于 Android 模拟器,但仅适用于某些 API
- nlp - 如果 LDA 设置为单个主题会发生什么?
- objective-c - 需要从 Qt 应用程序上的 CFStringRef 手动释放 NSString
- c# - GetDelegateForFunctionPointer 和 IPC?
- r - R中从字符串到日期的“0001-01-01”
- vuejs3 - Vue3:如何混合组合 API 和选项 API 以实现可组合/混合命名空间
- wso2 - WSO2 SCIM2 API 总是返回 401 Unauthorized
- kubernetes - Kubernetes 中的 calico + multus 静态 ip 配置
- xamarin - Xamarin 闪亮推
- powershell - 如何将 Powershell 命令的输出定向到 CMD 变量