Enum inheritance conflict

194 Views Asked by At

Suppose to have a base class that defines an enum like the following in its header file:

class Base{
    public:
        Base();

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

And a derived class that defines in a different enum the same variables but with different values:

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

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

Obviously I did a mistake, since I did not notice that A_VALUE and B_VALUE were already defined in the base class. Then I've used that values in my derived class implementation. Why I have not been warned by the compiler (Visual Studio 2013) that there was a conflict in that values? I could think that I was using the values of MyEnum2 instead of MyEnum1 or vice versa.

1

There are 1 best solutions below

0
On BEST ANSWER

Given the following code:

#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 will be printed.

This is because the identifier Derived::A_VALUE shadows that of Base::A_VALUE, and therefore an explicit cast to the base type must be made to access it. The same applies to other names defined at class scope, regardless of constness.

Here's a live example.

Why this doesn't yield a warning comes down to the implementation you're using, but there might be a variable shadowing warning that could cover this case. However, the standard does not have any concept of a warning, so there's no objective answer as to why your particular compiler isn't here (unless you send the implementers a message and ask, that is).

As others have said, strongly typed enums (C++11) do not have such an issue, as they must be accessed through the scope resolution operator ::, much like defining constants in a namespace.