私有构造函数和make_shared [英] Private constructor and make_shared

查看:144
本文介绍了私有构造函数和make_shared的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有私有构造函数的单例类.在静态工厂方法中,请执行以下操作:

I have a singleton class with a private constructor. In the static factory method I do the following:

shared_ptr<MyClass> MyClass::GetInstance()
{
    static once_flag onceFlag;

    call_once(onceFlag, []() {
        if (_instance == nullptr)
            _instance.reset(new MyClass());
    });

    return _instance;
}

如果我使用

_instance = make_shared<MyClass>();

代码无法编译.我的问题是:为什么 new 可以调用私有构造函数,而 make_shared 不能呢?

the code does not compile. My question is: why new can invoke a private constructor but make_shared not?

推荐答案

  1. 如前所述, std :: make_shared 或其组成部分无权访问私有成员.

  1. As mentioned, std::make_shared or its component parts don't have access to private members.

call_once once_flag 是不必要的.它们在c ++ 11静态初始化

the call_once and once_flag are un-necessary. They are implicit in c++11 static initialisation,

您通常不希望公开共享指针.

You normally would not want to expose the shared pointer.

 

class MyClass
{
    MyClass() {}

public:
    static MyClass& GetInstance()
    {
        static auto instance = MyClass();
        return instance;
    }
};

但是,在一种情况下,我可以想象您想在哪里公开指向该impl的共享指针-在这种情况下,该类可以选择中断"或重置"该impl为新的.在这种情况下,我将考虑这样的代码:

However, there is one case I can imagine where you would want to expose a shared pointer to the impl - this is in the case where the class can choose to 'break off' or 'reset' the impl to a new one. In this case I would consider code like this:

class MyClass2
{
    MyClass2() {};

    static auto& InternalGetInstance()
    {
        static std::shared_ptr<MyClass2> instance { new MyClass2 };
        return instance;
    }

public:

    static std::shared_ptr<MyClass2> GetInstance()
    {
        return std::atomic_load(std::addressof(InternalGetInstance()));
    }

    static void reset() {
        std::atomic_store(std::addressof(InternalGetInstance()),
                        std::shared_ptr<MyClass2>(new MyClass2));

    }  
};

但是,最后,我认为类的静态性"应该是实现的细节,而对类的用户而言并不重要:

However, in the end, it is my view that 'staticness' of a class should be an implementation detail, and unimportant to the user of the class:

#include <memory>
#include <utility>

class MyClass
{
    // internal mechanics

    struct Impl {

        auto doSomething() {
            // actual implementation here.
        }
    };

    // getImpl now becomes the customisation point if you wish to change the
    // bahviour of the class later
    static Impl& getImpl() {
        static auto impl = Impl();
        return impl;
    }


    // use value semantics - it makes for more readable and loosely-coupled code
public:
    MyClass() {}

    // public methods defer to internal implementation

    auto doSomething() {
        return getImpl().doSomething();
    }
};


int main() {

    // note: just create objects
    auto mc = MyClass();
    mc.doSomething();

    // now we can pass the singleton as an object. Other functions don't even
    // need to know it's a singlton:

    extern void somethingElse(MyClass mc);
    somethingElse(mc);
}

void somethingElse(MyClass mc)
{

}

这篇关于私有构造函数和make_shared的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆