【问题标题】:Inconsistent behaviour accessing private nested class definition访问私有嵌套类定义的行为不一致
【发布时间】:2012-10-02 19:36:11
【问题描述】:

我的代码将子类模板声明为私有,然后将成员声明为受保护:

class X {
private:
    template <class T>
    class Y {
    public:
        void somethingToDo();
        // definition
    };
protected:
    Y<SomeType> _protectedMember;
    // More definition
};

class Z : public virtual X{
public:
    void f();
}
void Z::f() {
    ...
    _protectedMember.somethingToDo();
}

最初我用 gcc 4.3.4 编译它并接受它。然后我将它发送出去,尝试在各种平台上针对 GCC、IBM 和 Microsoft 编译器进行构建,但非 gcc 编译器拒绝了它。现在 似乎 是对(这个版本的)gcc 标准合规性的控诉。但在得出任何结论之前,我想验证一下技术上的正确性。

谢谢。

【问题讨论】:

  • 假设您的意思是 Z::fpublic, the newest GCC correctly rejects the code
  • 我的意思是让 Z::f 公开。我会解决这个问题。
  • Y&lt;T&gt;::somethingToDo 真的是私有的吗?
  • SomeType 似乎未定义。你能发布一个完整的、最小的、实际程序来演示这个问题吗?见SSCCE.ORG
  • FWIW,this program 使用 g++4.7 和 g++-4.5 编译。

标签: c++ standards standards-compliance


【解决方案1】:

您的程序对我来说似乎是有效的(嗯,除了 Y::somethingToDo 是荒谬的私有)。 Z::f() 不要求访问任何 private 名称,仅要求访问 protected 名称。

如果Z::f() 试图引用Y&lt;T&gt;,那么编译器应该会出错。但是Z::f() 只能访问_protectedMember,这肯定是允许的。

【讨论】:

    【解决方案2】:

    我很确定我以前见过这个。当时它是 GCC 中的 known bug,此后已得到修复。

    【讨论】:

    • 这听起来很相似,我不确定它是否与在这种情况下访问受保护成员的错误相同。在这种情况下,访问应该或不应该被允许的类型定义。
    【解决方案3】:

    Y 模板是私有的,不能在非私有代码中使用,例如 _protectedMember 女巫旨在从派生类访问,您还应该将其声明为受保护,因此其成员对派生可见类。

    作为一般规则,如果您希望您的变量在某个范围内完全可访问,那么它的类型必须在该范围内完全可访问。当然,您的代码在以下情况下对当前设计很有用:

    class Base {
        class PrivateClass {};
    protected:
        PrivateClass _val;
        void doSomething( PrivateClass& v );
    }
    

    现在派生类可以使用_val 调用doSomething,但不能调用其方法或使用其属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-13
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-06
      相关资源
      最近更新 更多