3

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

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 标准合规性的控诉。但在得出任何结论之前,我想验证一下技术上是正确的。

谢谢。

4

3 回答 3

1

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

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

于 2012-10-02T19:56:47.620 回答
1

我很确定我以前见过这个。这是当时 GCC 中的一个已知错误,此后已得到修复。

于 2012-10-02T19:39:54.173 回答
0

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

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

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

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

于 2012-10-02T20:40:30.500 回答