c++ - 枚举继承冲突

标签 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 的值,反之亦然。

最佳答案

给定以下代码:

#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 的标识符,因此必须显式转换为基类型才能访问它。这同样适用于在类范围内定义的其他名称,无论常量如何。

Here's a live example .

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

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

关于c++ - 枚举继承冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30666006/

相关文章:

java - 将抽象类存储在数组列表中

c# - 扩展方法与继承

java - 如何正确使用class类型的参数?

c++ - 变量用作 C 中的函数参数后出错?

c++ - VS 2012 智能感知 - 功能可能未初始化

java - 在几个不相关的类中使用的 Java 中在哪里定义常量

c# - 关于Enum操作

php - MySQL枚举删除反斜杠

c++ - 使用 std shared_ptr 作为 std::map 键

c++ - 带有作用域链的 JS_EvaluateScript