1

如果我有一个具有私有构造的类,使用 gcc 4.6 从该类的成员函数中boost::make_shared()构造shared_ptr该类的一个将发出编译器错误。

#include "boost/shared_ptr.hpp"
#include "boost/make_shared.hpp"

class Foo
{
private:
    Foo(int a){};
public:
    static boost::shared_ptr<Foo> do_foo(){ return boost::make_shared<Foo>(5); }
    friend template boost::shared_ptr<Foo> boost::make_shared<Foo>( Arg1 && arg1, Args && ... args );
}

int main()
{
    auto f = Foo::do_foo();
}

调用Foo::do_foo将导致编译器错误。

有什么想法吗?

4

2 回答 2

3

不幸的是,没有指定哪个函数实际调用构造函数make_shared,所以你不能让那个函数成为朋友。如果你有一个像这样带有私有构造函数的类,那么你就不能用make_shared.

但是,您可以做的是创建一个派生类,该派生类具有一个调用适当基类构造函数的公共构造函数,并使该派生类成为朋友(因此它可以调用私有构造函数):

class Foo
{
private:  
    Foo(int a){};  
public:  
    static boost::shared_ptr do_foo();
    friend class DerivedFoo;
};

class DerivedFoo: public Foo
{
public:
    DerivedFoo(int a):
        Foo(a)
    {}
};

boost::shared_ptr<Foo> Foo::do_foo(){ return boost::make_shared<DerivedFoo>(5); }

如果DerivedFoo在 .cpp 文件中定义的匿名命名空间中,do_foo则其他 .cpp 文件中的函数仍然无法Foo直接构造DerivedFoo.

于 2010-09-24T21:55:39.323 回答
0

您至少需要在几个地方提供模板参数。

class Foo  
{  
private:  
    Foo(int a){};  
public:  
    static boost::shared_ptr<Foo> do_foo(){ return boost::make_shared<Foo>(5); }
    friend template boost::shared_ptr<Foo> boost::make_shared<Foo>( Arg1 && arg1, Args && ... args );
}  
于 2010-09-09T00:10:46.633 回答