我编写了一个带有 protected 构造函数的类,因此只能使用静态 create() 函数生成新实例,该函数将 shared_ptr 返回我的类。为了提供有效的分配,我想在 create 函数中使用 boost::make_shared,但是编译器提示说我的类构造函数在 boost::make_shared 中受到保护。我决定让我的 boost::make_shared 成为我类的 friend ,但我对语法感到困惑。我试过了
template< class T, class A1, class A2 >
friend boost::shared_ptr<Connection> boost::make_shared(const ConnectionManagerPtr&, const std::string&);
但是编译器给我语法错误。请帮忙。
最佳答案
您不需要模板化friend
部分,但您需要表明friend
函数是一个模板:
friend boost::shared_ptr<Connection> boost::make_shared<>(/* ... */);
// ^^
这适用于 Comeau 和当前的 GCC 版本,但不适用于 VC。更好的做法是以下形式:
friend boost::shared_ptr<Connection> boost::make_shared<Connection>(/* ... */);
这现在适用于多个编译器 - 我在 VC8、VC10、GCC 4.2、GCC 4.5 和 Comeau 4.3 上对其进行了测试。
或者使用限定名称来引用函数模板的特定实例,就像 Martin 应该 和 Comeau 一样工作,但 GCC 对此感到窒息。
一个不依赖于 make_shared()
实现细节的有用替代方法(因此也适用于 VC10s TR1 implementation )是使用 pass-key-idiom用于构造函数的访问保护并与 create()
函数成为 friend ,例如:
class Connection {
// ...
public:
class Key {
friend boost::shared_ptr<Connection> create(const ConnectionManagerPtr&,
const std::string&);
Key() {}
};
Connection(const ConnectionManagerPtr&, const std::string&, const Key&);
};
boost::shared_ptr<Connection> create(const ConnectionManagerPtr& p,
const std::string& s)
{
return boost::make_shared<Connection>(p, s, Connection::Key());
}
关于c++ - 如何让 boost::make_shared 成为我类(class)的 friend ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3378520/