放置上的析构函数 - 新
destructor on placement-new
本文关键字:析构函数 更新时间:2023-10-16
是否有一种模式可以在堆栈上自动调用放置新初始化对象的析构函数,当它退出作用域时?我想跳过记忆来显式调用析构函数的需要。或者,是否有与放置-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
会更简单。
已经有一个标准的包装器模板类可以做到这一点 -std::unique_ptr
.
注意评论中的注意事项
#include <cstdio>
#include <cstdlib>
#include <string>
#include <memory>
class aclass {
public:
aclass(int size);
~aclass();
int size_;
char data[0]; // this is illegal in standard c++
};
// deleter which only calls destructor, does not deallocate
struct inplace_deleter
{
template<class T>void operator()(T* p) const noexcept
{
p->~T();
}
};
void f(int size)
{
// VLAs are not standard c++. This is a compiler extension on gcc.
char v[sizeof(aclass) + size];
using ptr_type = std::unique_ptr<aclass, inplace_deleter>;
auto p = ptr_type(new(&v) aclass(size));
// auto deleted
}
int main()
{
f(10);
f(100);
return 0;
}
https://godbolt.org/z/qEwld-
相关文章:
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误