Question

I'm trying to mimic Java enum in C++, so I created code that look like this (of course I removed anything that's not related to my question):

MyEnum.hpp

MyEnum
{
public:
    class Value1;
    class Value2;

    static Value1 VALUE1;
    static Value2 VALUE2;

private:
    MyEnum(std::string name);
};

class MyEnum::Value1 public MyEnum
{
private:
    Value1();
};

class MyEnum::Value2: public MyEnum
{
private:
    Value2();
};

I made the costructors private, so that the only instance of enum values are static members of BaseEnum. How to define them?

MyEnum.cpp

MyEnum::Value1 VALUE1=MyEnum::Value1();

This gives me

error: calling a private constructor of class 'MyEnum::Value1'

EDIT: That was too simple. I've just forgotten to add MyEnym:: to the values. One of many small every day problems I encounter when coming back to C++ from Java. Also, in the code from my question, I forgot to add friend declaration, which was in my original code. Thanks for your answers.

Was it helpful?

Solution 2

First of all to answer your question: the correct text in

MyEnum.cpp

is:

MyEnum::Value1 MyEnum::VALUE1;

But this still won't work, because you're not automatically a friend of your parent. So also add

friend class MyEnum;

in the declaration of class MyEnum::Value1

OTHER TIPS

Assuming you don't use C++11 to do it, here's the solution - make classes friends to each other, so that Enum class can instantiate subclasses, and subclasses can call base class constructor, I also added missing parts to make the code compilable:

class MyEnum
{
public:
    class Value1;
    class Value2;

    friend class Value1;
    friend class Value2;

    static Value1 VALUE1;
    static Value2 VALUE2;

private:
    MyEnum(std::string name) {}
};

class MyEnum::Value1 : public MyEnum
{
    friend class MyEnum;
private:
    Value1() : MyEnum("VALUE1") {}
};

class MyEnum::Value2 : public MyEnum
{
    friend class MyEnum;
private:
    Value2() : MyEnum("VALUE2") {}
};

MyEnum::Value1 MyEnum::VALUE1;
MyEnum::Value2 MyEnum::VALUE2;

int main()
{
    // Use statuc enum value
    MyEnum::Value1 &someValue = MyEnum::VALUE1;

    return 0;
}

Declaring something as private implies that only the class members itself and friends have access to it, not its base class, nor its children. Therefore, by declaring the constructors private, you prevent instantiation from anywhere but the class and its friends. If you really want MyEnum to access the private members of its children you have to define it as a friend within each of them:

friend class MyEnum;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top