Is it possible to force std::make_shared
to use a class's new operator? This relates to another SO question. According to that question, std::make_shared
uses a custom allocator:
From the standard (ยง20.7.2.2.6 shared_ptr creation ):
Effects: Allocates memory suitable for an object of type T and constructs an object in that memory via the placement new expression ::new (pv) T(std::forward(args)...).
As such, I thought that I could use a custom placement new operator, but that appears to be false
// 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;
}
which gives
---Creating foo
Foo constructor
---Creating foo2
Foo new
Foo constructor
---Creating foo3
Foo constructor
---fin
Foo destructor
Foo destructor
Foo delete
Foo destructor
Also tucked in there was an attempt to force an allocator that would call the custom new operator with the call to std::allocate_shared
. In any case, is there a way to make std::make_shared
call the custom new operators without defining a whole new allocator?