Thread: Could someone please clarify enums for me

  1. #16
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    here is a straightforward usage of traditional enums in a reasonable size project to manage my error output in a lottery wheel generator i wrote some time back, the enum is defined in a header and whenever a new error needs to be reported on i can just add a member to the enum list and drop a new message in my switch, easy.

    Code:
    void WGen::ShowValidateMsg(int msg_type) 
    {
    	
        if(msg_type == HIGHPERM_WARN)
        {
            warnWin->show();
            carryOnBtn->take_focus();
            warnOutp->insert("Be aware the current settings mean very high permutations and may cause your computer to become unresponsive\n");
            warnOutp->insert("You may wish to change the 'From' value if your machine has a slow or 'old' processor speed\n");
            warnOutp->insert("NOTE: If you are loading an external wheel then ensure it is properly constructed\nSEE HELP\n");
        }
        else
        {
            errorWin->show();
            errorBtn->activate();
            errorBtn->take_focus();
            errorOutp->copy_label("ERROR!");
        }
    
    	mainWin->deactivate();
    
    	if(TWopened)
    	{
    		writeWin->deactivate();
    	}
    
    	switch (msg_type)
    	{
    		case WTYPE_ERR:   //wintype
    		{
    			errorOutp->insert("EC#01: Win must be minimum of 2, maximum of 6! See HELP" );
    		}
    		break;
    		case WTYPE_ERR2:   //wintype
    		{
    			errorOutp->insert("EC#02: Win has to be at least the same as Nums A Line and less than 7!\nSee HELP" );
    		}
    		break;
    		case IFMATCH_ERR: //ifmatch
    		{
    			errorOutp->insert("EC#03: You must at least match the value of 'Win' or a maximum of 6.\nSee HELP");
    		}
    		break;
    		case T_USING_ERR: //totusing
    		{
    			errorOutp->insert("EC#04: You must use at least the 'If Match amount of numbers, or a maximum of the max for your game, e.g 49.\nSee HELP");
    		}
    		break;
    		case LINELEN_ERR: //numsaline
    		{
    			errorOutp->insert("EC#05: Choice must be at least the same as 'Win' and less than 'From' and a maximum of the max you can bet on for your lotto game. eg UK lotto = 6.\nSee HELP");
    		}
    		break;
    		case T_LINES_ERR: //totlines
    		{
    		    errorOutp->insert("EC#06: Total Lines x Nums A Line must be at least equal to 'From' or you won't use all the numbers\n");
    			errorOutp->insert("Also check: Total Lines must not exceed the permutations of 'Nums A Line' and 'From' Or duplicate lines would be required.\nSee HELP");
    		}
    		break;
    		case HIGHLINE_ERR:
    		{
    			errorOutp->value("EC#07: The maximum lines you can play in this program version is 5000, See HELP");
    		}
    		break;
    	}
    }
    Last edited by rogster001; 04-22-2013 at 12:50 PM.
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  2. #17
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128
    Quote Originally Posted by laserlight View Post
    I note that for the scenarios that killme and dwks presented, encoding the type as an enum is not necessarily the best design choice, depending on the requirements. For example, it might be better to create a class hierarchy instead, and then deal with (smart) pointers/references to objects of the subclasses and override virtual functions instead of using an if-else chain to check the types via enum.
    If I recorded myself saying this, added noise and then played it back to myself in reverse, it would make as much sense as this does to me at my stage of learning. I will come back to this in a years time and (hopefully) will know what you're saying.

    @rogster, that kind of makes sense to me.

    I think my questions don't have an easy answer right now. I feel a natural progression will lead me into a situation where I will say to myself "hey, enums would be useful here!". Then it'll click into place. That's the theory anyway.

    *edit*
    I found this pretty useful: http://indiedevelopment.co/c-intro-t...torial-part-7/ although I'm unsure about the &FunctionChoice passing back to main bit at 12:56. Downloading the source file to mess about with it.
    Last edited by samwillc; 04-22-2013 at 02:15 PM.

  3. #18
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I think my questions don't have an easy answer right now. I feel a natural progression will lead me into a situation where I will say to myself "hey, enums would be useful here!". Then it'll click into place. That's the theory anyway.
    I'm against the idea that everything in C++ is a treasure chest full of secrets. dwks gave you about as thorough an answer as you need.

    And just to explain the example in the original post, you should be thinking: Well, a traffic light has 3 lights, red, yellow, and green. Using an enum is one way of making these three states understandable.

    You could also do:
    Code:
    const int RED = 0, YELLOW = 1, GREEN = 2;
    But note that enums give the constants a type name, so they are somewhat more cohesive. You should think of enums as finite sets of constants. You can refer to the named constants, specifically, by their type name.
    Code:
    enum LightColor {RED, YELLOW, GREEN};
    In C++, that is pretty much all they are. If you make the topic too broad, you will confuse yourself.

    I found this pretty useful: http://indiedevelopment.co/c-intro-t...torial-part-7/ although I'm unsure about the &FunctionChoice passing back to main bit at 12:56. Downloading the source file to mess about with it.
    Well, if it helps... personally I am very suspicious of video lessons -- it really depends on the source. JRandomLoser is probably teaching you the way he learned, which is not always a complete treatment of the subject or useful.

    The bit about references that you refer to is a stylistic choice.

    Code:
    void function (int &functionChoice);
    A reference and a void return type can be used instead of a return value. In some cases this is a compromise. Say you want to return two things, or maybe the actual return value is already used to do something else. Then, you have limited choices in front of you.

  4. #19
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128
    Quote Originally Posted by whiteflags View Post
    In C++, that is pretty much all they are. If you make the topic too broad, you will confuse yourself.
    I think this is happening right now.

    Quote Originally Posted by whiteflags View Post
    The bit about references that you refer to is a stylistic choice.

    Code:
    void function (int &functionChoice);
    A reference and a void return type can be used instead of a return value. In some cases this is a compromise. Say you want to return two things, or maybe the actual return value is already used to do something else. Then, you have limited choices in front of you.
    I thought that may be the case after watching the video again, a normal return value (as I have used) would also 'put back in main' or however he puts it. I am very aware that people teach the way they know, which is not always the best way. However, I'm not doing any C++ whatsoever in my degree and would have liked to have learned it from an established institution. As the only programming they teach is Java, my only option is to try and sort the wheat from the chaff when it comes to C++. Of course, this isn't easy when you're just starting something.

  5. #20
    Registered User
    Join Date
    Jun 2012
    Location
    Morden, UK
    Posts
    128
    Thanks to all who have helped so far. So I have put this together with the snippets outlined along the way.

    Code:
    #include <iostream>
    #include <string>
    
    enum CarType {CT_FORD, CT_MUSTANG, CT_SKODA};
    
    enum CarType pickCarType(const std::string &userInput) {
          
        if(userInput.length() > 0 && userInput[0] == 'F') {
            // if user input starts with an F, assume they really want a Ford
            return CT_FORD;
        }
        
        // otherwise, give them a random car type
        int number = std::rand() % 2;
        return (enum CarType)(number + 1);  // cast the number to a CarType.
    }
    
    int main()
    {
        std::string userInput;
        
        std::cout << "What type of car would you like?";
        std::cin >> userInput;
        
        int chosenCar = pickCarType(userInput);
        
        switch (chosenCar)
        {
            case CT_FORD: //this makes more sense than case 0
                std::cout << "Good choice!";
                break;
            case CT_MUSTANG: //this makes more sense than case 1
                std::cout << "Excellent choice!";
                break;
            case CT_SKODA: //this makes more sense than case 2
                std::cout << "Great choice!";
                break;
        }
        
    }
    So the whole thing is a bit nonsensical for a program, but it demonstrates the point to me in the fact that the cases at the bottom make a lot more sense if there is a word in there rather than a number. I think this is all I really needed to see before moving on.

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Because people are so sloppy... here's the fixed code.
    Code:
    #include <iostream>
    #include <string>
     
    enum class CarType { Ford, Mustang, Skoda };
     
    CarType PickCarType(const std::string& UserInput)
    {    
        if(UserInput.length() > 0 && UserInput[0] == 'F')
        {
            // if user input starts with an F, assume they really want a Ford
            return CarType::Ford;
        }
         
        // otherwise, give them a random car type
        int number = std::rand() % 2;
        return static_cast<CarType>(number + 1);  // cast the number to a CarType.
    }
     
    int main()
    {
        std::string UserInput;
         
        std::cout << "What type of car would you like?";
        std::cin >> userInput;
         
        int ChosenCar = PickCarType(userInput);
         
        switch (ChosenCar)
        {
            case CarType::Ford: //this makes more sense than case 0
                std::cout << "Good choice!";
                break;
            case CarType::Mustang: //this makes more sense than case 1
                std::cout << "Excellent choice!";
                break;
            case CarType::Skoda: //this makes more sense than case 2
                std::cout << "Great choice!";
                break;
        }
    }
    Requires a C++11 compiler.
    See how it doesn't pollute the parent scope now? That's good. Now we don't need to add it all in CAPS, nor do we need some stupid prefix. I mean, we already know it's a car type, so why do we have to prefix everything with "CARTYPE"? Plus, it's now type safe. See this for more information: C++11 - Wikipedia, the free encyclopedia
    Also, you don't need to prefix "enum" before the type. You had to in C, but this is C++.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #22
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Because people are so sloppy... here's the fixed code.
    I wish to note specially that "fixed" in this context means that the code has been updated to comply to fairly recent changes in the C++ standard (which explains what C++ is as a language). People are only "sloppy" because C++11 wasn't originally used.

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I also meant that people are sloppy in that they mix C++03 and C++11 enums and even old C enums, never even bothering to mention what kind of enum it is.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #24
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Good point.

    For the record: C enums are C++ enums. For much of C++'s life, there was no appreciable difference between the two kinds of enums. In fact, the creator of C++ actually encouraged this: he wanted C at the time to compile as C++, so C++ supported C features.

    Now we don't need to add it all in CAPS, nor do we need some stupid prefix.
    The enum "stupid prefix" not being required is new. In fact, I had to look it up to comment, because it was required up until C++11. And it is required for the initial declaration, whether it is scoped or not. If it is scoped, (if the enum has a name) then you can refer to it by name, otherwise it is exactly like the enums of previous versions of C++.

    Other than that, the wikipedia article does a good job explaining what the differences now are if you use C++11.

  10. #25
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Because people are so sloppy... here's the fixed code.
    O_o

    Wow. Really!?

    So, you actually posted to complain about people posting sloppy code and completely failed to get the code you posted right while illustrating intent that clearly violates the very reason you forward the feature you are proselytizing?

    1): Didn't fix the variable names.
    2): Didn't add the necessary header.
    3): Didn't change the type storing the result of the function.
    4): Didn't make the point of using namespaces instead of simple naming schemes even without C++11 features.

    *shrug*

    Because of this the benefit of safe `enum' is completely lost on anyone who doesn't already know the feature.

    *sigh*

    Way to show people how it's done, Elysia.

    [Edit]
    To be clear, I have no problem with your trying to champion the cause of C++11. (Of course, I'd still have a problem if you didn't tell people that what you were suggesting was a C++11 feature, but I haven't seen you not note the C++11 requirement in a while.) You just did a lousy job here making the new feature look like a sideways movement.
    [/Edit]

    The enum "stupid prefix" not being required is new. In fact, I had to look it up to comment, because it was required up until C++11. And it is required for the initial declaration, whether it is scoped or not.
    He isn't talking about the `enum' keyword, and in the implied context from earlier, not the post by Elysia, the `enum' keyword isn't required for the same reason `struct' is not required in similar situations.

    That said, he was referring to the naming scheme of C `enum' of prefixing values with `CT_' or whatever as is appropriate to the enumeration, but yeah, that isn't required, and it certainly isn't necessary even in C++98 thanks to namespaces.

    Soma
    Last edited by phantomotap; 04-23-2013 at 06:19 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. asymptotic notation clarify
    By monkey_c_monkey in forum Tech Board
    Replies: 6
    Last Post: 10-05-2012, 06:12 PM
  2. Clarify pass by reference
    By monkey_c_monkey in forum C++ Programming
    Replies: 3
    Last Post: 08-29-2012, 10:01 PM
  3. Can someone clarify what a 'slow event' is.
    By Overworked_PhD in forum Networking/Device Communication
    Replies: 2
    Last Post: 01-13-2008, 05:11 PM
  4. Can someone clarify this comment.
    By Overworked_PhD in forum C Programming
    Replies: 2
    Last Post: 05-15-2007, 10:17 PM
  5. Clarify
    By Mr. Squirrel in forum Windows Programming
    Replies: 0
    Last Post: 12-02-2001, 04:35 PM