简体   繁体   中英

C++ Class Constructor Arguments From Limited List

I am wondering what was the best way using C++ to make a class constructor take an argument from a limited list. For example, if I have a class called Colour , then the constructor would only accept Red , Green , or Blue and store the value to a private variable. Then I would have a method called printColour which would print the variable.

Currently, I've been able to get this to work:

#include <iostream>
using namespace std;

class MyClass
{
public:
    typedef enum { A = 3, B = 7 } Options_t;
    MyClass(Options_t);
    void printVal(void);
private:
    Options_t _val;
};

MyClass::MyClass(Options_t val)
{
    _val = val;
}

void MyClass::printVal(void)
{
    cout << _val << endl;
}

MyClass hi(MyClass::A);

int main(void)
{
    hi.printVal();
    return 0;
}

However, the :: notation to access the class's struct seems a bit clunky (I want to write an Arduino Library so it might be beginners needing to use the constructor / methods.

Is there any better way to do this (maybe with . notation?) Thanks!

Edit: When I try to compile with MyClass x(2) ( int instead of Options_t ), I get this error:

class_enums.cpp:24:9: error: no matching constructor for initialization of 'MyClass'
MyClass hi(2);
        ^  ~
class_enums.cpp:4:7: note: candidate constructor (the implicit copy constructor) not viable: no known
      conversion from 'int' to 'const MyClass' for 1st argument
class MyClass
      ^
class_enums.cpp:14:10: note: candidate constructor not viable: no known conversion from 'int' to
      'MyClass::Options_t' for 1st argument
MyClass::MyClass(Options_t val)
         ^

So it seems that I can't just use an int as the argument?

If you just want this during creation of hi, then you can do

MyClass hi(hi.A);

However, in your class, you must use the namespace accessor :: . The . is to access a member of an instance, not the actual class stuff.

They probably explained it better here: When do I use a dot, arrow, or double colon to refer to members of a class in C++? and here: What is the difference between "::" "." and "->" in c++

Thanks for the help! In the end I decided to go with this code (below) because according to this link, ints are not implicitly converted to an enum value.

Code:

#include <iostream>
using namespace std;

typedef enum { C = 1, D = 6 } Options;

class MyClass
{
public:
    MyClass(Options);
    void printVal(void);
private:
    Options _val;
};

MyClass::MyClass(Options val)
{
    _val = val;
}

void MyClass::printVal(void)
{
    cout << _val << endl;
}

MyClass hi(C);

int main(void)
{
    hi.printVal();
    return 0;
}

Also, doing it this way, I can define a struct for all the Options for the class, then just pass by reference to the constructor, like so:

#include <iostream>
using namespace std;

typedef enum { C = 1, D = 6 } Options;
typedef struct
{
    Options opt;
} MCConfig;

class MyClass
{
public:
    MyClass(Options);
    MyClass(MCConfig &);
    void printVal(void);
private:
    Options _val;
};

MyClass::MyClass(Options val)
{
    _val = val;
}

MyClass::MyClass(MCConfig & conf)
{
    _val = conf.opt;
}

void MyClass::printVal(void)
{
    cout << _val << endl;
}

MyClass hi(C);

int main(void)
{
    hi.printVal();
    MCConfig c;
    c.opt = D;
    MyClass m(c);
    m.printVal();
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM