如何为朋友函数中定义的类授予友谊?

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】:

这是关于本地类的标准部分的第一段:

类可以在函数定义中声明;这样的类称为本地类。本地类的名​​称在其封闭范围内是本地的。本地类在封闭作用域的范围内,并且对函数外的名称具有与封闭函数相同的访问权限。

【讨论】:

谢谢!我想确认行为是明确定义的,你的回答很清楚

以上是关于如何为朋友函数中定义的类授予友谊?的主要内容,如果未能解决你的问题,请参考以下文章

如何为构造函数包含 HttpClient 和一些字符串的类设置一些 .NET Core 依赖注入?

android如何为自定义的类传递参数?

如何为联合成员提供一个简单的类构造函数?

C++ lambda 友谊

如何为具有自引用指针的类实现复制构造函数/赋值运算符?

如何为 react-native-camera 使用 refreshAuthorizationStatus 函数