c++ - 委派到私有(private)领域

标签 c++ operator-overloading private delegation pimpl-idiom

有时,C++ 的隐私概念让我感到困惑 :-)

class Foo
{
    struct Bar;
    Bar* p;

public:

    Bar* operator->() const
    {
        return p;
    }
};

struct Foo::Bar
{
    void baz()
    {
        std::cout << "inside baz\n";
    }
};

int main()
{
    Foo::Bar b;   // error: 'struct Foo::Bar' is private within this context

    Foo f;
    f->baz();     // fine
}

由于 Foo::Barprivate,我不能在 main 中声明 b。但是我可以从 Foo::Bar 调用方法就好了。为什么这是允许的?这是意外还是有意为之?


哦,等等,它变得更好了:

Foo f;
auto x = f.operator->();   // :-)
x->baz();

即使我不能命名类型 Foo::Bar,它也可以与 auto 一起使用...


诺亚写道:

type names defined within a class definition cannot be used outside their class without qualification.

只是为了好玩,以下是从外部获取类型的方法:

#include <type_traits>

const Foo some_foo();

typedef typename std::remove_pointer<decltype( some_foo().operator->() )>::type Foo_Bar;

最佳答案

试图在标准中找到可以详细说明的任何内容,但我做不到。我唯一能找到的是9.9:

类型名称遵循与其他名称完全相同的范围规则。特别是,在类定义中定义的类型名称不能在没有限定的情况下在其类之外使用。

本质上,Foo::Bar 的 name 是 Foo 私有(private)的,而不是定义。因此,您可以在 Foo 之外使用 Bars,只是不能按类型引用它们,因为该名称是私有(private)的。

成员的名称查找规则似乎对此也有一些影响。我没有看到任何专门引用“嵌套类”的东西,因此它们不会被允许(如果我实际上找不到任何东西是因为它不存在)。

关于c++ - 委派到私有(private)领域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2952216/

相关文章:

swift 。让我们重写但不调用该方法

c++ - 在 QT 中构建类似时间轴的布局

java - Java的翻译过程是什么?

c++ - 你能制作自己的渲染管线吗?

c++ - 在 C++ 中重载全局运算符 new/delete

binding - boost python重载运算符()

ios - SecItemAdd 在 OS X 上不工作,在 iOS 上工作

C++ 初始化类成员对象

c# - 重载 operator== 与 Equals()

javascript - 使用 Jest 的 rewire 来监视私有(private)函数中使用的 console.log