Please simplify my code.

Started by
42 comments, last by rip-off 11 years, 9 months ago

*snip*

Templates may not be perfect, but if you don't see their value, you haven't been using C++. [font=courier new,courier,monospace]std::string[/font] works because of templates, [font=courier new,courier,monospace]std::cout/cin[/font] work because of templates, <algorithm> works because of templates, [font=courier new,courier,monospace]std::vector[/font] works because of templates, etc. In your own code, templates can help a ton too (for making a generic resource cache, for example, or making a vector (mathematical vector, that is) or matrix library, rather than duplicating the code, increasing the amount of work it is to maintain everything).


But if you do'nt use classes, I don't think it's C++ code either. tongue.png

There is so much wrong with that statement I'm not even going to try to correct it...

But we're getting side tracked now, and I think some of these discussions would be better in a new thread. Let's not hijack the OP's thread.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Advertisement

For the love of all things holy, people, please trim the quotes!

[quote name='antiHUMANDesigns' timestamp='1340549821' post='4952326']
Oh, you're right, I'm known to suffer from over-engineering complex. Might be my asperger acting up. But I'm sorry, I just can't agree that using OOP ever makes for bad C++, even in small applications. We might have different viewpoints on this, and I think neither of us would go as far as to shout "Truth!™". Properly formatted and divided into separate files, even small programs look and feel so much better to work with in OOP. And I still think it makes them easier to update and whatnot.
But in this very thread, to me it's about advocating abstraction.

It's not that you just over-engineered stuff. It's that it's not very good code. You wrote an empty constructor (why?), you used a C header (<time.h> (the C++ version is <ctime>)), you're using C-style casts (instead of C++ style casts), you're not including the header to use [font=courier new,courier,monospace]s/rand()[/font], you're using the [font=courier new,courier,monospace]s/rand()[/font] from C (and not the [font=courier new,courier,monospace]s/rand()[/font] from C++), etc. You're being hypocritical of the "you're using C, not C++." And as rip-off showed, you're using OOP wrong. There is no need for SlotMachine to be a class (it's got one function, and no member variables). There's no need for the Application class either, as idiomatic C++ wouldn't be using classes like that. If you want evidence that not everything needs to be in a class, take a look at the <algorithm> header. Some programming languages have done the disservice of teaching people that Everything Is An Object And Belongs In A Class, which is so far from true it's not even funny. OOP is great, but it's unfortunate that it's so misunderstood, and teaching a beginner to over engineer isn't doing him/her any favors.

For what it's worth, I commend you for trying to help. The reason I'm being a bit harsher than normal though is because you're being quite stubborn and this is in For Beginners, where details matter.

And for the record, you can do OOP in C. It's not just a C++ thing. C++ never meant for everything to be wrapped up in a class, and it intended for free standing functions to be used in addition to its other features that complement OOP.
[/quote]

Ah, man, I tried to re-write the OP's code as quickly as possible, and I made the constructor thinking I would put something there, and ended up not doing so, but leaving it like that. I didn't know it would come under scrutiny. Most people just write small snippets of code (or even pseudo-code) to show something, but I undertook to re-write it all as an example for a beginner, but it ended up being scrutinized by professionals instead. Had I known...

<time.h> instead of <ctime>, once again an honest mistake from trying to rush it. Doesn't change the point I was trying to make, though. If you look back, it's about the C++ way of thinking, not which libraries you use.

I disagree that SlotMachine shouldn't be a class. This is a quick prototype, or a first-version of the "game". If I wanted to add things to the slot machine, having it as a class already is a good thing. You might not like it, but to be completely frank and brutally literal, I don't give a shit, because it wasn't written for your enjoyment. It's C++, it compiles without errors, I like it, it allows for further development nicely... I'm happy with it.
In OOP, the slot machine is an object. I stand by that. I don't see how it matters what the class contains. The slot machine is an object, and when I pull it's lever, that's a method for that object (or, member function). Making it a function is not OOP, making it a variable won't work, so what would you make it? I chose to make it a class, and until until you can change my mind as to why it shouldn't be (performance is not an issue in this application, for example), I stand firm.

And I don't put everything in a class either. In my own projects, I have "lose" functions for getting random floating point values, for example. I never said everything needs to be a class, but I do claim that some things should be classes, because it makes logical sense if you consider how they are being handled. I can probably find some way to make a getRandomFloat() function to become an object, by looking at it like a pseudo-random number generator, but I don't see how I would make an actual slot machine into a function or a variable, and not feel silly about it.

[quote name='antiHUMANDesigns' timestamp='1340554577' post='4952357']
*snip*

Templates may not be perfect, but if you don't see their value, you haven't been using C++. [font=courier new,courier,monospace]std::string[/font] works because of templates, [font=courier new,courier,monospace]std::cout/cin[/font] work because of templates, <algorithm> works because of templates, [font=courier new,courier,monospace]std::vector[/font] works because of templates, etc. In your own code, templates can help a ton too (for making a generic resource cache, for example, or making a vector (mathematical vector, that is) or matrix library, rather than duplicating the code, increasing the amount of work it is to maintain everything).


But if you do'nt use classes, I don't think it's C++ code either. tongue.png

There is so much wrong with that statement I'm not even going to try to correct it...

But we're getting side tracked now, and I think some of these discussions would be better in a new thread. Let's not hijack the OP's thread.
[/quote]

I obviously use std::string from time to time. If I don't see their value, that doesn't mean I'm not using C++. I don't understand your logic here. My personal disposition towards certain bits of code has no impact on what language I am writing in. None whatsoever. It's like saying I don't drive a car just because I chose to never use the cigarette lighter, which is a part of the car.
But let me repeat it to make it clear: I do use std::string sometimes. I'm not bothered by it. Can we start scrutinizing your preferences now? This is starting to feel like a witch hunt. Really.

EDIT: OH, btw, when I say "...then I don't think it's C++ code either", then that is obviously an opinion, seeing as I used the word "think". Now, I see why you don't want to try to "correct" my opinion. Thank you for that.
I think the OP probably has more than enough research to do now into the merits and problems associated with the various C++ paradigms. If everyone could try to get the focus back to topic of improving the OP's code rather than the more general argument I'm sure they would appreciate that.

@Sid_TheBeginner

The major source of complexity in your original program was that your main() function was trying to do too much work. This results in a convoluted program flow, with lots of nested conditionals, loops and variables. By breaking it into smaller functions, like antiHUMANDesigns and I did, you can focus the program logic on the current point of interest.

A minor source of complexity are your use of infinite loops with explicit loop control via "break" and "continue". Instead, prefer to write loops with actual conditions. Another area causing issues are declaring your variables at the start of the program. This results in all the variables being "in scope" for the entire function. This can be partially addressed by splitting your program into smaller functions, but even then readability is improved if you only declare / define your variables at the tightest possible scope.

If I take your code and paste it into my IDE, I get the following warnings:

1>c:\path\to\project\help.cpp(18): warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
1>c:\path\to\project\help.cpp(42): warning C4806: '==' : unsafe operation: no value of type 'bool' promoted to type 'int' can equal the given constant
1>c:\path\to\project\help.cpp(14): warning C4101: 'exit' : unreferenced local variable
1>c:\path\to\project\help.cpp(16): warning C4101: 'restart' : unreferenced local variable
[/quote]
On my system, I have my warnings set to the second highest level, and I've told the compiler to treat warnings as errors. As a result, your code doesn't built on my system. As a beginner, each of these warnings indicates a probable problem with your program.


  • The first one is a bit of a false positive. The compiler is complaining that passing the result of time() to srand() results in loss of data, but the data is not important. This warning can be suppressed by using an explicit cast to let the compiler know we are ok with this: static_cast<unsigned>(time(NULL)). Please note that casting to quiet the compiler is not a wise move unless you know what you are doing - I've seen many bugs in beginner's code caused by overusing casting to "fix" compiler errors and warnings.

  • The unsafe operation highlights a bug in your program - the condition r0 == r1 == r2 == 7 is incorrect. You are comparing the outcome of r0 == r1 (a boolean value) to r2 - r2 being a number between 2 and 7 will never test equal. The outcome of this comparison - which as I mentioned is always false or 0 - is compared with 7. Intentionally or unintentionally, you've rigged your slot machine to never pay out the maximum reward!

  • Both the "exit" and "restart" variables can simply be removed.


You should configure your compiler to have the highest warning levels and to treat warnings as errors. This will prevent such bugs from creeping in.

This topic is closed to new replies.

Advertisement