 variables defined within a function. They are created at the point of variable definition, and destroyed when the block they are declared in is exited. They can only be accessed inside the block in which they are declared.
Global variables are variables defined outside of a function. They
Hi Chetan!
I've added comments to your code, feel free to ask any questions that may come up.
Dear nascardriver!
is it ok if I skip this due to the lack of my understanding in enums?
Hi Ali!
You can skip it but you'll come across enums sooner or later.
enums are just a bunch of named integers.
Ali, I'm usually quick to understand things, but I struggle a bit with enumerations, too. Your problem may be like mine: I keep looking for some "there" there that just isn't there - some great purpose and use for them. Although they're a "cool" concept, there's so little practical use for them that you have to almost contrive ways to use them. And you end up having to use a series of if statements or a switch statement to make use of them anyway, so why bother using them? I've concluded that the best thing about them is that they're a good way to document in english on the spot what a coded number means.
for example:
if (monsterType == 0)
bad: what does that number code 0 mean?
if (monster.type == MonsterType::OGRE)
much better!
Personally, I use enumerations all of the time. More than many of the other concepts in C++. Why? Because they allow us to define sets of things and give them descriptive names. As you note above, MonsterType::OGRE is much more descriptive than the literal 0. Also, enums pair really well with arrays (something we discuss in chapter 6), so you can use an enumerator as an array index. For example, inventory[ItemTypes::TORCH] is much more meaningful than inventory[0].
Pretty much anywhere you are thinking about using an integer to identify or select from a small set of well-defined objects, an enumerated value is a better choice.
Here's my take on this chapter's quiz. I found that using an enum class seemed to generate more work than it saved (though that is probably because of how I used it). I recall the lesson on enums mentioning that they don't play nicely with std::cin but I gave it a go anyway. What I can say is that this quiz gave me a new appreciation for all of those games I played growing up. I can't imagine what a fully-functional game's code must look like!
Hi Matt!
Nice code once again, here are my two cents:
General: Inconsistent use of '\n' and std::endl
@spawnMonster: Don't hardcode enum ids and don't let the user input an id directly, this will cause problems when modifying the @MonsterType enumeration or when the user enters an invalid id. Using a separate function to convert string <> int <> MonsterType is better (Use a switch statement like you did in @printMonster).
Line 28: Use std::numeric_limits<std::streamsize>::max() instead of 32767 for real applications (Doesn't matter here)
Line 32: That's correct
@printMonster: Imagine you want to return a string or write to a file rather than writing directly to std::cout, that's going to be a lot of work updating this function. Constructing a string containing the full sentence and writing that string to std::cout is more portable.
Hi Matt!
I pretty much understood everything from your code but what did you do in line 28?
oh and are you just a starter? because it doesn't seem so 🙂
std::cin.ignore ignores all characters in the input stream until the given character ('\n') is reached (inclusive).
You don't need to understand this now, it's part of lesson 5.10.
and in line 29? sorry for my mistake 😉 and also please answer the question i just posted 😉
He's converting the int @x to a MonsterType. This is covered in lesson 4.5.
Ali Dahud,
Thanks, I'm flattered but I am indeed a novice. In all honesty though, I started going through this series a couple years ago and made it to lesson 3 or so before I got deployed and forgot everything. That said, this is my second voyage through the material up to this point. Even so, I still have to regularly refer back to previous lessons to remember how to do something, which I think is OK, not many people remember 100% of what they learn on the first exposure. Alex and nascardriver still find things that can be improved with my code so I'm far from the example to emulate - just a fellow student like you!
I think your questions have already been answered. Best of luck!
Regards,
Matt
Hello,
In lesson 4.4b - An introduction in std::string , i would appreciate if was an example like in this quiz using a function of std::string.But great lessons to learn ! Thank you.
So basically if i understood this,its not recommended doing this :
#include <iostream>
using namespace std; // This is not recommended,right?
int main() etc.
I dont like using 'using namespace std;' myself, i prefer writing full std::cout/cin/string.
I know its useful if std starts to repeat but only INSIDE functions,not at pure beginning of program,rigt?
Hi Andreas!
> its not recommended doing this
Yep
> I know its useful if std starts to repeat but only INSIDE functions,not at pure beginning of program,rigt?
You mean having a using directive inside a function instead of an entire file?
It's not as bad, but it's still bad.
Hi, I have a quick question about namespaces and structs. I placed the enum code for the quiz inside the struct block so I could experiment:
Since all
versions have to be replaced with
versions I wanted to implement a using directive or using declaration instead of replacing every MonsterType with Monster::MonsterType however I wasn't able to get it to work properly. I tried
and
How would one go about getting namespaces to work in this situation, if it's at all possible? Thanks!
Hi Sirius!
Those assume that @Monster is a namespace. @Monster isn't a namespace so it doesn't work.
What you are looking for is a type alias
See lesson 4.6 (Typedefs and type aliases)
Thank you for the solution! Would you warn against placing enums inside structs in this manner?
I quite like the aesthetic of grouping the variables together this way (and it does save some space) but I understand that it could be difficult to debug or understand if you're viewing the program for the first time, especially with type aliases all over the place.
"Would you warn against placing enums inside structs in this manner?"
I rarely use structs, classes do everything a struct does and more, so there's rarely a reason to use a struct over a class.
You can place enums inside structs no problem but if you're planning on type aliasing the enum everywhere you might just as well place the enum outside.
My opinion is if an enum is tied to the struct or class, placing the enum inside the struct or class is better than outside, as it makes it clearer that the two are bound together. Generally when I do this, I use enum instead of enum class though (since the class or struct provides a namespacing effect).
Chpt4.cpp
funciones.h
monster.h
Hi Alex, can you help me explain the different between the following statements?
Although they are both acceptable in complier, I guess type 1 is more efficient than type2 ?
They should be identical -- both do aggregate initialization. #2 uses the classic style, whereas #1 uses the uniform initialization style (introduced in C++11).
My code
vs c++11 solution
Is my solution okay, or in any way less efficient?
Could printing the type like I did instead of returning a string be useful for something else in a program or would a string just do the same and more?
Thanks
If all you need to do is print the name, then having a function that just prints the name is probably more efficient than returning a string and having the caller do the print. It's just less reusable since the caller can do anything with a string, but a function that prints can only print.
Short answer: Since you don't need the string anywhere else, your code is fine. 🙂
#include "stdafx.h"
#include <iostream>
#include <string>
enum class MonsterType
{
OGRE,
DRAGON,
ORC,
SPIDER,
SLIME
};
struct Monster
{
std::string name;
int health;
MonsterType type;
};
std::string getMonsterType(Monster monster)
{
if (monster.type == MonsterType::OGRE)
return "Ogre";
if (monster.type == MonsterType::DRAGON)
return "Dragon";
if (monster.type == MonsterType::ORC)
return "Orc";
if (monster.type == MonsterType::SPIDER)
return "Giant Spider";
if (monster.type == MonsterType::SLIME)
return "Slime";
return "Unknown";
}
void printMonster(Monster monster)
{
std::cout << "This " << getMonsterType(monster) << " is named " << monster.name << " and has " << monster.health << "health\n";
}
int main()
{
Monster OGRE = { MonsterType::OGRE, "Trog", 145 };
Monster SLIME = { MonsterType::SLIME, "Blurp", 24 };
printMonster(OGRE);
printMonster(SLIME);
return 0;
}
My code is almost identical but am getting some errors related to convert MonsterType to a std::string.
I'm using Visual Studio 2017.
The issue is that order of the members of the struct Monster don't match the order in which you're initializing your members in OGRE and SLIME. You'll need to make them consistent.
Can you please list the programs which can be made till these topics , so that we can practice them at home .
I don't understand the question. Can you rephrase?
I think he means what can he make from the knowledge thus far. Like certain games, programs. Not like it is possible to make something other than a terminal-game.
Oh. At this point, you're limited to programs that input and output from/to the terminal, and execute mostly linearly. After next chapter (loops), your options for interesting programs increase significantly.
Hey!
This is what I made up. Is it a lot worse than the one in your example? 🙂
Thanks for the site btw, it's just great and I think I'm starting to get a hang of this a bit at a time.
Structurally the program looks good, you're just doing a few things that are less efficient. First, you're unnecessarily casing enumerators of type MonsterType to integers, when that's not necessary. Second, you're returning string literals as std::string when all you're doing is printing them. Returning char* would avoid an unnecessary conversion.
Thanks. Haha, yeah I actually ran into an error that I couldn't understand and get past until I used the static casts. 🙂 Now that I look at your example I see the problem was in my struct and all I tried fixing was in the getMonsterType function and the monster creation.
But I guess realizing your own errors and how to fix them may be the hardest part. 😀.
I'm confused. shouldn't you use arguments in line 50?
Yes, he should. 'error: 'auto' I get this error: "error: non-static data member declared 'auto'". ';' after declaration specifiers " pointed at the first line of the code 'struct...'.
Name (required)
Website