【问题标题】:Inaccessibility when friend struct inherits class朋友结构继承类时无法访问
【发布时间】:2014-01-09 20:29:42
【问题描述】:

我有一种情况,我想隐藏一个基类并限制可以从它继承的类:

namespace _detail {
    class Private abstract final {
        struct Base abstract {
        protected:
            Base() {}
        };

        friend struct ::A;
        friend struct ::B;
        friend struct ::C;
    };
}

struct A : _detail::Private::Base {}; //error
struct B : _detail::Private::Base {}; //error
struct C : _detail::Private::Base {}; //error

编译器告诉我ABC 无法访问_detail::Private::Base,即使它们是Private 的朋友。我以前使用过这种模式没有问题,与我使用它的其他时间相比,我真的看不出这里有什么不同。我没看到什么?

【问题讨论】:

  • friend struct A; 将命名空间 _detail 中的结构声明为朋友。
  • @sftrabbit 它有效,为什么不呢?
  • @DyP 抱歉忘了放 :: 运算符
  • @sftrabbit visual C++,见msdn
  • 现在您需要前向声明。但是它应该可以工作(对于标准 C++,忽略 abstract)。

标签: c++ inheritance visual-c++ friend access-control


【解决方案1】:

C++ 语言不允许您在友元声明中使用限定名(如::A),除非这些限定名引用先前声明的实体。实际上,这条规则几乎无处不在,不仅在友元声明中:限定名称必须引用先前声明的实体。

在您的情况下,您在朋友声明 friend struct ::A 中使用了限定名称 ::A。为此,编译器必须事先知道来自全局命名空间的struct A。在您的情况下,A 未在此时声明,这使得 friend struct ::A 声明格式错误。它甚至不应该按照语言的正式规则进行编译。

如果您的编译器接受这一点,您必须查阅您的编译器文档以了解其含义。我怀疑未知::Afriend struct ::A 被解释为等同于friend struct A,即它将_detail::A 声明为朋友。

如果您在声明命名空间 _detail 之前进行前向声明 struct A;,它可能会使其按预期工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2022-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多