c – 是否可以强制`std :: make_shared`使用类的new运算符?

前端之家收集整理的这篇文章主要介绍了c – 是否可以强制`std :: make_shared`使用类的new运算符?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
是否可以强制std :: make_shared使用类的new运算符?这与另一个 SO question有关.根据那个问题,std :: make_shared使用自定义分配器:

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)…).

因此,我认为我可以使用自定义展示位置新运算符,但这似乎是错误

// 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调用自定义新运算符而不定义一个全新的分配器?

解决方法

不,这是不可能的(使用make_shared).

由于T类的自定义分配器通常会被编写和优化(例如使用池)以期望分配大小为T,而make_shared将分配更多的内存,我想这不是一个重要的支持功能.

此外,该标准为您希望使用自定义分配器的情况提供allocate_shared.

猜你在找的C&C++相关文章