2

I'm attempting my first bigger C++ object and I'm running into a bit of a problem when it comes to implementing a singleton using a shared pointer.

When I try to compile the following, I Visual Studio gives me this error:

"Error C2248 'PaletteManager::PaletteManager': cannot access private member declared in class 'PaletteManager' {omitted}\xmemory line 228"

I'm guessing the issue is because I have a private constructor/destructor and make_shared is trying to call the constructor. This access problem makes sense to me, but if I want to use a shared pointer as the way to access my singleton object, what am I supposed to do? The code works just fine with a raw pointer, but I wanted to try and do things the clean way with a smart pointer.

Here is the header file for the code in question:

class PaletteManager
{
private:

    // array representing palette colors
    uint* paletteColors;

    // private constructor/destructor because singleton
    PaletteManager();
    ~PaletteManager();

    // load palette from file TODO: not implemented
    void loadPallette();

    static std::shared_ptr<PaletteManager> instance;

public:

    const uint PALETTE_MAX_COLORS = 4;

    uint getPaletteColor(uint idx);

    // singleton accessor
    static std::shared_ptr<PaletteManager> getInstance();
};

And here is the function at issue in the cpp file:

std::shared_ptr<PaletteManager> PaletteManager::instance = nullptr;

std::shared_ptr<PaletteManager> PaletteManager::getInstance()
{
    if (!PaletteManager::instance) 
    {
        PaletteManager::instance = std::make_shared<PaletteManager>();
    }

    return PaletteManager::instance;
}
1

2 Answers 2

3
PaletteManager::instance = std::make_shared<PaletteManager>();

This results in std::make_shared attempting to new a PalletteManager object, and then construct a std::shared_ptr from it. This is what std::make_shared does, that's how it works.

This is not going to work here: that's because PalletteManager has a private constructor, and std::make_shared, the template in the C++ library, is not it's friend.

You will have to explicitly new the object in getInstance, a member of this class, which can use the private constructor, and then manually construct the std::shared_ptr from the pointer to this new object.

TLDR: you cannot use std::make_shared for an object with a private constructor. C++'s rules do not allow you to do that.

Sign up to request clarification or add additional context in comments.

Comments

0

You can make std::make_unique<>() a friend function of your class with the private constructor. Presumably this would work with std::make_shared<>() too? (But I haven't tested it.)

For example, see: How to make std::make_unique a friend of my class

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.