5

Possible Duplicate:
How do I call ::std::make_shared on a class with only protected or private constructors?

I want to create a shared pointer to a class, and have a factory method that returns it while keeping the constructor\destructor protected. since the shared pointer can't access the the constructor or the destructor, I get compiler errors.

I am using llvm 4.1, but I am looking for a solution that can be compiler independent (besides making the constructor\destructor public).

this is a code sample:

class Foo
{
public:
    static std::shared_ptr<Foo> getSharedPointer()
    {
        return std::make_shared<Foo>();
    }

protected:
    Foo(int x){}
    ~Foo(){}

};

any Ideas?

Community
  • 1
  • 1
danny
  • 319
  • 3
  • 9
  • 1
    And http://stackoverflow.com/questions/3541632/using-make-shared-with-a-protected-constructor-abstract-interface http://stackoverflow.com/questions/7521660/friend-function-of-stdmake-shared http://stackoverflow.com/questions/2590310/can-i-use-boostmake-shared-with-a-private-constructor etc. – interjay Oct 16 '12 at 18:00
  • And http://stackoverflow.com/questions/8202530/how-can-i-call-a-private-destructor-from-a-shared-ptr for the destructor issue – interjay Oct 16 '12 at 18:02

1 Answers1

2

Just allocate the pointer yourself instead of calling make_shared:

static std::shared_ptr<Foo> getSharedPointer()
{
    return std::shared_ptr<Foo>(new Foo);
}

Note, however, that this would require making the destructor public.

syplex
  • 1,147
  • 6
  • 27
  • 2
    this may solve the constructor error, but not the destructor. also it has performance issues since it will perform an extra memory allocation – danny Oct 16 '12 at 18:03
  • 2
    There are good reasons to use `make_shared` including fewer heap allocations and better locality of reference. – Jonathan Wakely Oct 16 '12 at 18:04
  • @danny please describe the extra memory allocation. – syplex Oct 16 '12 at 18:07
  • @syplex `shared_ptr` also needs to do some bookkeeping for the tracked type (e.g. number of other `shared_ptr` / `weak_ptr`) pointing to the object. With your code there's the allocation for `Foo` and an extra one for this additional info. With `make_shared` there's be a single allocation call made for `sizeof(Foo) + sizeof(BookkeepingInfo)` – Praetorian Oct 16 '12 at 18:09
  • 1
    @Jonathan Wakely the OP didn't specify using make_shared as a requirement, only using shared_ptr. While you may be correct in the shortcomings, this solution seems much more clear and straightforward. – syplex Oct 16 '12 at 18:13
  • @Prætorian + something for alignment purposes :P – R. Martinho Fernandes Oct 16 '12 at 18:34
  • @syplex, except it fails due to the protected destructor, which _was_ a requirement. So clear and straightforward and doesn't work. With a custom deleter it could work. – Jonathan Wakely Oct 16 '12 at 23:02