Enum Class Constructor C++ , How to Pass Specific Value

Passing enum as parameter to a constructor

Now you've finally posted enough code, we see that this

chips m_doubloon(DOUBLOON);

is actually a class member declaration. Class members can't be initialised with (), only with = or {}. Assuming your compiler supports in-class initialisation (introduced in C++11), you should be fine with

chips m_doubloon{DOUBLOON};
^ ^

Alternatively, you could initialise the members in the constructor's initialiser list rather than in their declarations.

Pass enum class as a parameter of constructor

You can prevent Employee e3({}); by declaring an initializer_list constructor. This is always preferred when the initializer is a braced list:

Employee(std::initializer_list<int>) = delete;

The template type doesn't really matter.

However it is not possible to prevent a caller casting some value to EmployeeType and then providing that as constructor argument.

How to pass an enum value to the constructor of a class through reflection?

The solution

If you have an enum's Type and want to create it's instance from it's name, do so by using Enum.Parse. Then you can create your external class instance like this:

object enumInstance = Enum.Parse(providerType, "SqlClient");
object externalClassInstance = Activator.CreateInstance(externalClassType, new object[]{"param1", "param2", enumInstance });

If you want to create an enum's instance from it's value, you can do so by using Enum.ToObject, like this:

object enumInstance = Enum.ToObject(providerType, 0);
object externalClassInstance = Activator.CreateInstance(externalClassType, new object[]{"param1", "param2", enumInstance });

Why can't I just pass an integer?

There seems to be some confusion why using Enum.ToObject is necessary. This is because an Enum is not an Int32, nor does it inherit from it (it couldn't - all structs in .NET are sealed). The confusion comes from the fact that you can cast an integer to a specific enum, and get it's instance:

ProviderType enumInstance = (ProviderType)0; // Works just fine

This works because all enums have an explicit cast operator from Int32. When you do so, internally the enum calls Enum.ToObject. When you call Activator.CreateInstance, it does not try to perform a cast or conversion, and tries to use the integer value as a parameter to the constructor. And since the class being created doesn't contain a constructor which takes an int, you get a MissingMethodException.

Also, enums don't even have to be int based, they can be a byte, sbyte, short, ushort, int (default), uint, long, or ulong. You can read more about it here.


Passing enum to a constructor

First of all, you should make Color protected or public. One simple way to make Color from enum to string is to use an array.

class Shape {
public:
enum Color {
Red = 0, // although it will also be 0 if you don't write this
Orange, // this will be 1
Yellow,
Green
};

};

class Rectangle : public Shape {
public:
Rectangle(int x, int y, int B, int H, Color color);
};

string getColorName(Shape::Color color) {
string colorName[] = {"Red", "Orange", "Yellow", "Green"};
return colorName[color];
}

void test() {
// now you may call like this:
Rectangle r(1,2,3,4, Shape::Red);
// get string like this:
string colorStr = getColorName(Shape::Yellow);
}

Enum class C++11 by reference or value

It is not inheriting the primitive type but rather it tells the implementation to use the specified type(unsigned short) as the underlying type for the enumerators.

You can just simply treat the enum class object as any other class object and apply the same rules while passing it to functions.

  • If you want to modify the enum class object inside function, pass it by reference.
  • If you just want to read the object inside function pass it by constant reference.

Move semantics are a language run-time performance enhancing feature which makes use of opportunities to move from rvalues instead of applying copy semantics which are performance intensive. r-value references and move semantics are not only limited to move constructor and move assignment operator but they can also be used with other functions. If you have scenarios which can make use of this optimization it is perfectly fine to make use of them.

C++ enum class with constructor

No, C and C++ enums are just a bunch of constants grouped together. C++ enum classes are the same, but to access them you need to add the name of the enum class as a "namespace".

How to pass an enum value to a constructor

Something like this

new Book( title, ........ ,Category.anyEnumConstant);

For ex:

   Book book=  new Book( title, ........ ,Category.Fiction);

Then inside the constructor

 this.category = categ;

User Defined C++11 enum class Default Constructor

A type defined with enum class or enum struct is not a a class but a scoped enumeration and can not have a default constructor defined. The C++11 standard defines that your PinID pid = PinID(); statement will give a zero-initialization. Where PinID was defined as a enum class. It also allows enum types in general to hold values other than the enumerator constants.

To understand that PinID() gives zero initialization requires reading standard sections 3.9.9, 8.5.5, 8.5.7 and 8.5.10 together:

8.5.10 - An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized

8.5.7 - To value-initialize an object of type T means: ... otherwise, the object is zero-initialized.

8.5.5 - To zero-initialize an object or reference of type T means: — if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T;

3.9.9 - States that enumeration types are part of the set of types known as scalar types.

A possible solution:

To meet your points 1 to 5 you could write a class along the lines of:

class PinID
{
private:
PinID(int val)
: m_value(val)
{}

int m_value;

public:
static const PinID N4;
static const PinID N17;
/* ...etc... */

PinID()
: m_value(N4.getValue())
{}

PinID(const PinID &id)
: m_value(id.getValue())
{}

PinID &operator = (const PinID &rhs)
{
m_value = rhs.getValue();
return *this;
}

int getValue() const
{
return m_value;
}

// Attempts to create from int and throw on failure.
static PinID createFromInt(int i);

friend std::istream& operator>>(std::istream &is, PinID &v)
{
int candidateVal(0);
is >> candidateVal;
v = PinID::createFromInt(candidateVal);
return is;
}
};

const PinID PinID::N4 = PinID(4);
/* ...etc... */

That can give you something that you would have to make specific efforts to get an invalid values into. The default constructor and stream operator should allow it to work with lexical_cast.

Seems it depends how critical the operations on a PinID are after it's creation whether it's worth writing a class or just handling the invalid values everywhere as the value is used.

Enum type as parameter in constructor

If i understand your question, you want to pass the type of the enum to the constructor of your class, something like this:

class FileDialogMenu
{
readonly Type enumType;

public FileDialogMenu(Type enumType)
{
this.enumType = enumType;
}
}

If so you have no problem at doing this:

new FileDialogMenu(typeof(ImageFileMask));

And the you can do (inside your FileDialogMenu class):

if (Enum.IsDefined(enumType, extension))

Well at least that is what i've understood.



Related Topics



Leave a reply



Submit