使用make_shared与受保护的构造函数+抽象接口 [英] Using make_shared with a protected constructor + abstract interface

查看:1843
本文介绍了使用make_shared与受保护的构造函数+抽象接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个抽象接口和从该接口派生的实现,其中构造函数被保护(创建这些对象只能从类工厂获得 - 实现DI模式),如何在工厂函数中使用make_shared ?



例如:

  class IInterface 
{
public:
virtual void Method()= 0;
};

class InterfaceImpl:public IInterface
{
public:
virtual void方法(){}

protected:
InterfaceImpl (){}
};

std :: shared_ptr< IInterface> Create()
{
std :: shared_ptr< IInterface> object = std :: make_shared< InterfaceImpl>();
return object;
}

make_shared显然不能访​​问InterfaceImpl中的受保护的构造函数,我有以下错误

  
错误C2248:'InterfaceImpl :: InterfaceImpl':无法访问在类' InterfaceImpl'

所以这里读取(问题: http://stackoverflow.com/questions/3378520/how-to-make-boostmake-shared-a-friend -of-my-class ),我尝试将以下内容放入实现类中:

  
friend std :: shared_ptr< InterfaceImpl> std :: make_shared< InterfaceImpl>();

它仍然无法编译。所以,然后我把另一个IInterface类。仍然没有快乐。我在这里做错了什么?



编辑:用于编译的完整源文件,带有friend...

 code> #include< memory> 

class IInterface
{
public:
friend std :: shared_ptr& lt; IInterface>创建();
virtual void Method()= 0;
};

class InterfaceImpl:public IInterface
{
public:
virtual void Method(){}

protected:
friend std :: shared_ptr& lt; IInterface>创建();
InterfaceImpl(){}
};

std :: shared_ptr< IInterface> Create()
{
std :: shared_ptr< IInterface> object = std :: make_shared< InterfaceImpl>();
return object;
}

void main()
{
std :: shared_ptr< IInterface> i = Create();
}


解决方案

不工作 - 在 make_shared 中不会发生 InterfaceImpl 实例的构造,但在内部输入 std :: tr1 :: _ Ref_count_obj< Ty> :: _ Ref_count_obj(void)



只需在你的情况下使 Create()函数a friend ,并且不使用 $ interface





$ b: / ...
protected:
friend std :: shared_ptr< IInterface>创建();
InterfaceImpl(){}
};

std :: shared_ptr< IInterface> Create(){
return std :: shared_ptr< IInterface>(new InterfaceImpl());
}

...或使用自定义 make_shared



另一种方法是使用类似这样的东西 pass-key-idiom



class InterfaceImpl:public IInterface {
public:
class Key {
friend std :: shared_ptr< IInterface>创建();
Key(){}
};
InterfaceImpl(const Key&){}
};

std :: shared_ptr< IInterface> Create(){
std :: shared_ptr< IInterface> object =
std :: make_shared< InterfaceImpl>(InterfaceImpl :: Key());
return object;
}


Given an abstract interface and an implementation derived from that interface, where constructors are protected (creation of these objects only being available from a class factory - to implement a DI pattern), how can I make use of make_shared in the factory function?

For example:

class IInterface
{    
public:    
    virtual void Method() = 0;
};

class InterfaceImpl : public IInterface
{
public:
    virtual void Method() {}

protected:    
    InterfaceImpl() {}    
};

std::shared_ptr<IInterface> Create()
{
    std::shared_ptr<IInterface> object = std:: make_shared<InterfaceImpl>();    
    return object;
}

make_shared obviously cannot access the protected constructor in InterfaceImpl, or indeed in IInterface, giving me the following error


error C2248: 'InterfaceImpl::InterfaceImpl' : cannot access protected member declared in class 'InterfaceImpl'

So reading here (question: http://stackoverflow.com/questions/3378520/how-to-make-boostmake-shared-a-friend-of-my-class), I tried putting the following into the implementation class:


friend std::shared_ptr<InterfaceImpl> std::make_shared<InterfaceImpl>();

It still wouldn't compile. So then I put another one into the IInterface class too. Still no joy. What have I done wrong here?

EDIT: Full source file used to compile, with "friend"...

#include <memory>

class IInterface
{    
public:    
    friend std::shared_ptr&lt;IInterface> Create();     
    virtual void Method() = 0;
};

class InterfaceImpl : public IInterface
{    
public:     
    virtual void Method() {}

protected:    
    friend std::shared_ptr&lt;IInterface> Create();     
    InterfaceImpl() {}    
};

std::shared_ptr<IInterface> Create()
{
    std::shared_ptr<IInterface> object = std::make_shared<InterfaceImpl>();    
    return object;
}

void main()
{
    std::shared_ptr<IInterface> i = Create();   
}

解决方案

With VC10 the solution you linked to doesn't work - the construction of the instance of InterfaceImpl doesn't happen in make_shared, but in an internal type in std::tr1::_Ref_count_obj<Ty>::_Ref_count_obj(void).

I'd just make the Create() function a friend in your case and not use make_shared():

class InterfaceImpl : public IInterface {
// ...    
protected:
    friend std::shared_ptr<IInterface> Create();
    InterfaceImpl() {}
};

std::shared_ptr<IInterface> Create() {
    return std::shared_ptr<IInterface>(new InterfaceImpl());
}

... or use a custom make_shared() implementation that you actually can befriend without relying on ugly implementation details.

An alternative would be to use something like this pass-key-idiom:

class InterfaceImpl : public IInterface {
public:
    class Key {
        friend std::shared_ptr<IInterface> Create();
        Key() {}
    };
    InterfaceImpl(const Key&) {}
};

std::shared_ptr<IInterface> Create() {
    std::shared_ptr<IInterface> object = 
        std::make_shared<InterfaceImpl>(InterfaceImpl::Key());
    return object;
}

这篇关于使用make_shared与受保护的构造函数+抽象接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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