【发布时间】:2016-06-09 19:24:49
【问题描述】:
是否可以强制std::make_shared 使用类的新运算符?这与另一个SO question 有关。根据那个问题,std::make_shared 使用自定义分配器:
来自标准(§20.7.2.2.6 shared_ptr 创建):
效果:分配适合类型 T 对象的内存,并通过放置 new 表达式在该内存中构造一个对象 ::new (pv) T(std::forward(args)...)。
因此,我认为我可以使用自定义放置 new 运算符,但这似乎是错误的
// std::cout
#include <iostream>
// std::make_shared
#include <memory>
// Track what we're making
struct Foo {
Foo() {
std::cout << "Foo constructor" << std::endl;
}
Foo(Foo const & foo) {
std::cout << "Foo copy constructor" << std::endl;
}
Foo(Foo && foo) {
std::cout << "Foo move constructor" << std::endl;
}
Foo & operator = (Foo const & foo) {
std::cout << "Foo copy assignment" << std::endl;
return *this;
}
Foo & operator = (Foo && foo) {
std::cout << "Foo move assignment" << std::endl;
return *this;
}
void * operator new(std::size_t size) throw(std::bad_alloc) {
std::cout << "Foo new" << std::endl;
return ::operator new(size);
}
void * operator new(std::size_t size, void * p) throw() {
std::cout << "Foo placement new" << std::endl;
return ::operator new(size,p);
}
void* operator new (std::size_t size, std::nothrow_t const & nothrow_value)
throw()
{
std::cout << "Foo nonthrowing new" << std::endl;
return ::operator new(size,nothrow_value);
}
void operator delete(void * p, std::size_t size) {
std::cout << "Foo delete" << std::endl;
::operator delete(p);
}
~Foo() {
std::cout << "Foo destructor" << std::endl;
}
};
int main() {
std::cout << "---Creating foo" << std::endl;
auto foo = std::make_shared <Foo> ();
std::cout << "---Creating foo2" << std::endl;
auto foo2 = std::shared_ptr <Foo> (new Foo());
std::cout << "---Creating foo3" << std::endl;
auto foo3 = std::allocate_shared <Foo> (std::allocator <Foo>());
std::cout << "---fin" << std::endl;
}
给了
---Creating foo
Foo constructor
---Creating foo2
Foo new
Foo constructor
---Creating foo3
Foo constructor
---fin
Foo destructor
Foo destructor
Foo delete
Foo destructor
还有一个尝试强制分配器通过调用std::allocate_shared 来调用自定义新运算符。无论如何,有没有办法让std::make_shared 调用自定义的新运算符而不定义全新的分配器?
【问题讨论】:
-
Don't custom new(控制你自己的分配)和
make_shared(不为你自己的类型进行第二次分配)有一些相反的目标吗? -
请注意,
make_shared会为 counting block 分配一次而不是两次。 -
您引用的标准文本明确表示它使用
::new,即全局而不是您的自定义。