使用声明和访问修饰符的嵌套类

Posted

技术标签:

【中文标题】使用声明和访问修饰符的嵌套类【英文标题】:Nested class using declaration and access modifiers 【发布时间】:2015-12-02 21:06:24 【问题描述】:

在编译一些代码时,我遇到了一个编译器错误,这对我来说似乎很奇怪,并且与继承、嵌套类、使用声明和访问修饰符有关。

基本上,派生类型的目的是公开基类型的嵌套保护类。

以下简短的示例来演示该问题:

class Base

protected:

    struct Nested
    
        enum value_enum
        
            val = 0,
            val2,
            val3
        ;
    ;

;

class Derived : public Base

public:

    using Base::Nested;
;


int main(int argc, char** argv)

    //Base::Nested aa; // error, as (I) expected
    //Base::Nested::value_enum ab; // error, as (I) expected

    Derived::Nested ba; // works, as (I) expected
    Derived::Nested::value_enum bb; // MSVC error, as (I) did not expect


    return 0;

见live。

MSVC11 (v11.00.61030) 阻塞此代码并出现以下错误:

错误 C2248:“Base::Nested”:无法访问在“Base”类中声明的受保护结构

GCC 和 Clang 都可以正确编译,因此无法从标准中引用相关部分,我认为这是一个 MSVC 错误。

MSVC 有没有办法解决这个问题?

【问题讨论】:

我认为在编译时出错比在后面遇到问题要好。 由于受到保护,标准的 main 函数将无法访问它 @AliKazmi 什么是受保护的? Derived 更改Nested 的访问修饰符;在这种情况下它不受保护。此外,value_enumNested 内部不受保护。 Derived 类中尝试typedef Base::Nested::value_enum value_enum; @Hrant MSVC 不会抱怨typedef Base::Nested Nested(还有其他类型等;因为它只是一个 SSCCE)。我“喜欢”这个想​​法作为一种解决方法。 【参考方案1】:

对于 MSVC,以下解决方法有效:

class Derived : public Base

    public:

    using Base::Nested;
    typedef Base::Nested::value_enum value_enum; // add this
;

int main(int argc, char** argv)

    //Base::Nested aa; // error, as (I) expected
    //Base::Nested::value_enum ab; // error, as (I) expected

    Derived::Nested ba; // works, as (I) expected
    Derived::value_enum bb = Derived::value_enum::val; // now works in MSVC


    return 0;

【讨论】:

以上是关于使用声明和访问修饰符的嵌套类的主要内容,如果未能解决你的问题,请参考以下文章

GLSL中几个修饰符的简单讲解

JAVA中访问修饰符的作用

Java中各种(类方法属性)访问修饰符与修饰符的简单说明

Java包(访问修饰符的范围)String字符串StringBuilder类基本类型和引用类型

java修饰符的作用范围

Java中的修饰符