委托给私有部分

发布于 2024-09-03 22:51:54 字数 1019 浏览 12 评论 0原文

有时,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 一起工作得很好...


Noah 写道:

类定义中定义的类型名称不能在没有限定的情况下在类外部使用。

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

#include <type_traits>

const Foo some_foo();

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

Sometimes, C++'s notion of privacy just baffles me :-)

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
}

Since Foo::Bar is private, I cannot declare b in main. Yet I can call methods from Foo::Bar just fine. Why the hell is this allowed? Was that an accident or by design?


Oh wait, it gets better:

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

Even though I am not allowed to name the type Foo::Bar, it works just fine with auto...


Noah wrote:

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

Just for fun, here is how you can get at the type from outside:

#include <type_traits>

const Foo some_foo();

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仙女山的月亮 2024-09-10 22:52:11

我认为这是设计使然。您无法显式创建 Foo::Bar 的实例,但它可以从成员函数返回,然后您可以将其传递给其他成员函数。这使您可以隐藏类的实现细节。

I think this is by design. You cannot explicitly create instance of Foo::Bar but it could be returned from member functions and then you could pass it to other member functions. This lets you to hide implementation details of your class.

半透明的墙 2024-09-10 22:52:09

我无法提供完整的答案,但也许是一个起点。 C++ 1998 规范在第 11.3 段[class.access](第 175 页)下包含以下代码示例:

class A
{
    class B { };
public:
    typedef B BB;
};

void f()
{
    A::BB x;   // OK, typedef name A::BB is public
    A::B y;    // access error, A::B is private
}

在此示例中,私有类型通过公共typedef。尽管这与通过成员函数签名发布类型不同,但它是相似的。

I can't provide a full answer, but maybe a starting point. The C++ 1998 specification includes the following code example under paragraph 11.3 [class.access] (p. 175):

class A
{
    class B { };
public:
    typedef B BB;
};

void f()
{
    A::BB x;   // OK, typedef name A::BB is public
    A::B y;    // access error, A::B is private
}

In this example, a private type is "published" through a public typedef. Although it's not the same thing as publishing a type through a member function signature, it's similar.

遥远的她 2024-09-10 22:52:07

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

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

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

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

Trying to find anything in the standard that would spell it out in detail but I can't. The only thing I can find is 9.9:

Type names obey exactly the same scope rules as other names. In particular, type names defined within a class definition cannot be used outside their class without qualification.

Essentially, the name of Foo::Bar is private to Foo, not the definition. Thus you can use Bars outside of Foo, you just can't refer to them by type since that name is private.

The name lookup rules for members would also seem to have some effect on this. I don't see anything that specifically references "nested class" and thus they wouldn't be allowed to (if my lack of finding anything in fact is because it's not there).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文