如何为朋友函数中定义的类授予友谊?
Posted
技术标签:
【中文标题】如何为朋友函数中定义的类授予友谊?【英文标题】:How is friendship conferred for a class defined within a friend function? 【发布时间】:2015-02-26 02:27:29 【问题描述】:这个问题是不言自明的,但如果需要,这里有一个例子:
假设我有一个带有私有构造函数的类“Thing”,它是函数“make_thing”的朋友:
class Thing
friend std::shared_ptr<Thing> make_thing();
Thing()
std::cout << "Thing constructor" << std::endl;
;
“make_thing”函数内部定义了一个结构:
std::shared_ptr<Thing> make_thing()
// err: Thing::Thing() is private within make_shared
// auto thing = std::make_shared<Thing>();
// this is okay
struct AccessThing : public Thing
AccessThing() : Thing()
;
auto thing = std::make_shared<AccessThing>();
return thing;
这在 gcc 4.8.2、clang 3.5 和 msvc 2013 中编译和工作。我无法调用
make_shared<Thing>()
因为 Thing 有一个私有构造函数。但是,我可以通过创建一个带有公共构造函数的结构 (AccessThing) 来解决这个问题,该构造函数又调用 Thing 的私有构造函数,然后将其传递给 make_shared。对我来说,如果 AccessThing 是 Thing 的朋友,这是有道理的。
那么关于如何将友谊赋予在朋友函数中定义的结构/类的规则是什么?
【问题讨论】:
我无法用引用来支持这一点,但我的印象是该函数具有访问权限,而AccessThing
是函数中代码的一部分......除此之外,如果您想要控制谁可以创建您的对象并希望使用make_shared
,您可以使用构造函数密钥:将构造函数设为公开,但让它采用私有类型。友元函数将能够创建该类型的实例并通过 make_shared
将其传递给构造函数
是的,我想使用工厂函数并从中调用 make_shared。此 Q 中列出了一些方法(我也从中得出了我的尝试):***.com/questions/8147027/…,包括类似于您提到的构造函数键成语的方法。然而,在尝试将一个结构体放入一个友元函数并让它工作之后,我很好奇底层规则是什么。另外,这可能最适合另一个问题,但是使用 key 方法有什么好处吗?
【参考方案1】:
这是关于本地类的标准部分的第一段:
类可以在函数定义中声明;这样的类称为本地类。本地类的名称在其封闭范围内是本地的。本地类在封闭作用域的范围内,并且对函数外的名称具有与封闭函数相同的访问权限。
【讨论】:
谢谢!我想确认行为是明确定义的,你的回答很清楚以上是关于如何为朋友函数中定义的类授予友谊?的主要内容,如果未能解决你的问题,请参考以下文章