- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有以下问题:我在我的项目中使用自定义池分配器,每次我要分配任何具有新位置的对象时,也会隐式调用该对象的析构函数。
这里是源代码:
测试对象:
class Obj {
public:
Obj(const std::string& s) {
std::cout << "Constructor Called" << std::endl;
}
~Obj() {
std::cout << "Destructor Called" << std::endl;
}
};
主要内容:
int main()
{
void *pmemory;
pmemory = malloc(ONEGIG_SIZE);
PoolAllocator* poolAllocator = new PoolAllocator(sizeof(Obj), __alignof(Obj), ONEGIG_SIZE, pmemory);
Obj *obj1 = allocator::allocateNew(*poolAllocator, Obj("Hello")); //<-- const and dest is called
//......
return 0;
}
这是 Allocator 的源代码:分配新函数:
template <class T> T* allocateNew(Allocator& allocator, const T& t)
{
return new (allocator.allocate(sizeof(T), __alignof(T))) T(t);
}
池分配器:
PoolAllocator::PoolAllocator(size_t objectSize, u8 objectAlignment, size_t size, void* mem)
: Allocator(size, mem), _objectSize(objectSize), _objectAlignment(objectAlignment)
{
ASSERT(objectSize >= sizeof(void*));
//Calculate adjustment needed to keep object correctly aligned
u8 adjustment = pointer_math::alignForwardAdjustment(mem, objectAlignment);
_free_list = (void**)pointer_math::add(mem, adjustment);
size_t numObjects = (size-adjustment)/objectSize;
void** p = _free_list;
//Initialize free blocks list
for(size_t i = 0; i < numObjects-1; i++)
{
*p = pointer_math::add(p, objectSize );
p = (void**) *p;
}
*p = nullptr;
}
PoolAllocator::~PoolAllocator()
{
_free_list = nullptr;
}
void* PoolAllocator::allocate(size_t size, u8 alignment)
{
ASSERT(size == _objectSize && alignment == _objectAlignment);
if(_free_list == nullptr)
return nullptr;
void* p = _free_list;
_free_list = (void**)(*_free_list);
_used_memory += size;
_num_allocations++;
return p;
}
void PoolAllocator::deallocate(void* p)
{
*((void**)p) = _free_list;
_free_list = (void**)p;
_used_memory -= _objectSize;
_num_allocations--;
}
好像在Pool Allocator中allocate方法return op之后调用了析构函数!谁能解释为什么会这样?
最佳答案
... every time i am going to allocate any object with placement new, the destructor is also called on that object implicitly
不,析构函数也在一个 对象上调用。您只是错误地假设被销毁的对象是您的池中分配的对象。
直觉上,由于您的 allocateNew
函数将 something 的 const ref 作为参数,因此 something 必须存在,这意味着它已被创建在你的池中分配任何东西之前。
虽然详细,
Obj *obj1 = allocator::allocateNew(*poolAllocator, Obj("Hello"));
将:
Obj("你好")
使用 std::string
构造函数创建一个新的匿名临时对象,它将记录您看到的消息
allocateNew(Allocator& 分配器, const T& t)
将 const ref 传递给该匿名临时变量到您的 allocateNew
函数中。
返回新的 (...) T(t)
在你的池中放置新的另一个对象,使用隐式生成的复制构造函数它不记录任何内容
返回指向池中分配的新对象的指针
在语句末尾超出范围时销毁匿名临时文件。
如果您想准确了解正在发生的事情,请实现日志记录版本所有 构造函数(和赋值运算符)变体。
如果你想避免临时对象 + 复制,传递一个 T&& t
并移动构造到池中。
关于c++ - 每次我使用 placement new 分配时都会隐式调用析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44306499/
我开始考虑在我 future 的项目或重构中实现控制反转容器,我想知道在正确设计依赖项时哪些原则(除了 GoF 模式)可能需要牢记在心。假设我需要构建一个简单的控制台应用程序,如果它可以访问互联网,它
假设我有一个 RxC contingency table 。这意味着有 R 行和 C 列。我想要一个维度为 RC × (R + C − 2) 的矩阵 X,其中包含行的 R − 1 “主效应”以及列的
我正在尝试使用 DKMS 为正在运行的内核 (4.4) 构 build 备树覆盖。我天真的 Makefile 如下: PWD := $(shell pwd) dtbo-y += my-awsome-o
我有一个 sencha touch 项目。我是用 phonegap 2.9 构建的,并且可以正常工作 device.uuid 返回到设备 ID。当我尝试使用 3.1 device.uuid 构建时抛出
我在安装了 Xcode 4.5.1 的 Mt Lion 上运行。 默认情况下,当我构建并部署到 iOS 5.1 设备时,显示会在我旋转设备时旋转,但当我部署到 iOS 6 模拟器或运行 iOS 的 i
我正在尝试使用 Google Analytics Reporting API v4 构建多折线图。 一张图表,其中我按每天的 session 计数为每个设备(台式机/平板电脑/移动设备)设置了一条线。
我一生都无法使用 xcode 组织者“自动设备配置”中的“团队配置配置文件”在 xcode 4.0.1 中将我的应用程序构建到我的 iPad 上。 该应用程序完美地构建到模拟器,但当我构建到 iPad
我是一名优秀的程序员,十分优秀!