枚举继承冲突

时间:2015-06-05 11:58:17

标签: c++ inheritance enums

假设有一个基类,它在头文件中定义了如下所示的枚举:

class Base{
    public:
        Base();

        enum MyEnum1{
           A_VALUE=1, 
           B_VALUE=2
        };
};

派生类在不同的枚举中定义相同的变量但具有不同的值:

class Derived : public Base{
    public:
        Derived();

        enum MyEnum2{
           A_VALUE=3, 
           B_VALUE=4
        };
};

显然我犯了一个错误,因为我没有注意到A_VALUE和B_VALUE已经在基类中定义了。 然后我在派生类实现中使用了这些值。 为什么我没有被编译器(Visual Studio 2013)警告该值存在冲突?我可以认为我使用的是MyEnum2而不是MyEnum1的值,反之亦然。

1 个答案:

答案 0 :(得分:0)

给出以下代码:

#include <iostream>

class Base
{
public:  
    enum MyEnum1
    {
        A_VALUE = 1,
    };

    const int B_VALUE = 42;

    int C_VALUE = -2;
};

class Derived : public Base
{
public:
    enum MyEnum2
    {
       A_VALUE = 3,
    };

    const int B_VALUE = 180;

    int C_VALUE = 99;

    void test()
    {
        std::cout << A_VALUE << ' ';
        std::cout << static_cast<const Base*>(this)->A_VALUE << ' ';

        std::cout << B_VALUE << ' ';
        std::cout << static_cast<const Base*>(this)->B_VALUE << ' ';

        std::cout << C_VALUE << ' ';
        std::cout << static_cast<const Base*>(this)->C_VALUE << std::endl;
    }
};

int main()
{
    Derived instance;
    instance.test();
}

3 1 180 42 99 -2将被打印。

这是因为标识符Derived::A_VALUE会影响Base::A_VALUE的标识符,因此必须对基类型进行显式强制转换才能访问它。这同样适用于在类范围内定义的其他名称,无论constness如何。

Here's a live example

为什么这不会产生警告取决于您正在使用的实现,但可能会有一个可变的阴影警告,可以涵盖这种情况。但是,该标准没有任何警告概念,因此没有客观答案为什么您的特定编译器不在此处(除非您向实施者发送消息并询问,即是)。

正如其他人所说,强类型枚举(C ++ 11)没有这样的问题,因为它们必须通过作用域解析运算符::来访问,就像在命名空间中定义常量一样。