LifePhilPsyPro
LifePhilPsyPro

Reputation: 49

Is there a way to force an object to be created on the heap with shared_ptr?

i was wondering if it is possible to force an object to be created on the heap by creating a private/protected desctuctor and by using shared_ptrs to ensure an automatic resource managment (the RAII features of a shared_ptr) at the same time. Can that be done in a different way maybe? The reason i ask that, is because from what i heard(didnt look at that yet) at the STL there are no virtual descructors,so there is no way to ensure safe destruction other than...shared_ptr? And if so,there is no way to force the object to the heap since shared_ptr is trying to access the destuctor. Anyway to bypass these limitations?

Upvotes: 2

Views: 2630

Answers (2)

Adrien Clerc
Adrien Clerc

Reputation: 2797

The answer by Mats is indeed wrong. The make_shared needs a public constructor. However, the following is valid:

class X
{
private:
    int x;

    X() : x( 42 ) {};
public:

    static std::shared_ptr<X> makeX()
    {
        return std::shared_ptr<X>( new X() );
    }
};

I don't like to use the new keyword, but in this case, it is the only way.

Upvotes: 1

Mats Petersson
Mats Petersson

Reputation: 129344

C++ is a language that puts the correctness of the code in the hand of the programmer. Trying to alter that via some convoluted methods typically leads to code that is hard to use or that doesn't work very well. Forcing the hand of the programmer so that (s)he has to create an object on the heap even if that's not "right" for that particular situation is just bad. Let the programmer shoot him-/herself in the foot if he wants to.

In larger projects, code should be reviewed by peers (preferably at least sometimes by more senior staff) for correctness and that it follows the coding guidelines of the project.

I'm not entirely sure how "virtual destructors" relate to "safe destruction" and "shared pointers" - these are three different concepts that are not very closely related - virtual destructors are needed when a class is used as a base-class to derive a new class. STL objects are not meant to be derived from [as a rule, you use templates OR inheritance, although they CAN be combined, it gets very complicated very quickly when you do], so there is no need to use virtual destructors in STL.

If you have a class that is a baseclass, and the storage is done based on pointers or references to the baseclass, then you MUST have virtual destructors - or don't use inheritance.

"safe destruction", I take it, means "no memory leaks" [rather than "correct destruction", which can of course also be a problem - and cause problems with memory leaks]. For a large number of situations, this means "don't use pointers to the object in the first place". I see a lot of examples here on SO where the programmer is calling new for absolutely no reason. vector<X>* v = new vector<X>; is definitely a "bad smell" (Just like fish or meat, something is wrong with the code if it smells bad). And if you are calling new, then using shared pointer, unique pointer or some other "wrapping" is a good idea. But you shouldn't force that concept - there are occasionally good reasons NOT to do that.

"shared pointer" is a concept to "automatically destroy the object when it is no longer in use", which is a useful technique to avoid memory leaks.

Now that I have told you NOT to do this, here's one way to achieve it:

class X
{
    private:
       int x; 
       X() : x(42) {}; 
    public:
       static shared_ptr<X> makeX() { return make_shared<X>(); }
};

Since the constructor is private, the "user" of the class can't call "new" or create an object of this kind. [You probably also want to put the copy constructor and assignment operator in private or use delete to prevent them from being used].

However, I still think this is a bad idea in the first place.

Upvotes: 4

Related Questions