如果我有一个私有构造的类,使用boost :: make_shared在该类的成员函数内构造该类的shared_ptr将使用gcc 4.6发出编译器错误。
#include "boost/shared_ptr.hpp"
#include "boost/make_shared.hpp"
class Foo
{
private:
Foo(int a){};
public:
static boost::shared_ptr do_foo(){ return boost::make_shared(5); }
friend template boost::shared_ptr boost::make_shared( Arg1 && arg1, Args && ... args );
}
int main()
{
auto f = Foo::do_foo();
}
调用Foo::do_foo
将导致编译器错误。
有什么想法吗?
编辑包含可编辑的代码。
答案 0 :(得分: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
位于定义do_foo
的.cpp文件中的匿名命名空间中,则其他.cpp文件中的函数仍然无法直接构造Foo
的任何实例,并且用户将无法告诉他们实际拥有的是DerivedFoo
。
答案 1 :(得分: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 );
}