Thirst for knowledge!
Moderator: Coders of Rage
-
- Chaos Rift Newbie
- Posts: 21
- Joined: Mon Oct 03, 2011 10:58 am
Thirst for knowledge!
Hi.
So, I can program. Not great, but i can do the basics like functions, classes, pointers blah blah blah.
But now I want to be able to program properly, I'm a C++ programmer and my design would make even the sloppy coders a little worried, I want to be able to code without worrying that I'm going to have to go back and redesign everything just because I can't tell what's going on in my own program anymore, don't get me wrong, I don't mind rewriting my code but only if it's for a reason I couldn't foresee from the start.
So what would you guys recommend? are there any specific books, videos, articles and the like on properly using C++ in clean and beautiful ways? or should I just keep hammering at my technique until I eventually get it right?
maybe we could turn this in to a topic specifically directed at learning to use C++ objects etc to their proper and full extent? I know we have an educational topic already, but from my quick skim of it I didn't pick out anything like this .
So, I can program. Not great, but i can do the basics like functions, classes, pointers blah blah blah.
But now I want to be able to program properly, I'm a C++ programmer and my design would make even the sloppy coders a little worried, I want to be able to code without worrying that I'm going to have to go back and redesign everything just because I can't tell what's going on in my own program anymore, don't get me wrong, I don't mind rewriting my code but only if it's for a reason I couldn't foresee from the start.
So what would you guys recommend? are there any specific books, videos, articles and the like on properly using C++ in clean and beautiful ways? or should I just keep hammering at my technique until I eventually get it right?
maybe we could turn this in to a topic specifically directed at learning to use C++ objects etc to their proper and full extent? I know we have an educational topic already, but from my quick skim of it I didn't pick out anything like this .
-
- Chaos Rift Cool Newbie
- Posts: 78
- Joined: Mon Feb 21, 2011 2:55 am
- Current Project: Aleios Engine
- Favorite Gaming Platforms: PC, Dreamcast
- Programming Language of Choice: C++
- Location: Melbourne, Australia
Re: Thirst for knowledge!
This is, in a sense, pretty controversial. There really is no one way to code. Sure there might be some common patterns of which people follow but in the end it's really up to you how you structure things.
More importantly, it's usually based on what you are coding. Are you coding games? if so, what components would you need? (Audio, Graphics, Input, etc;).
I'm creating a framework for cross-platform development (kind of like SDL/SFML) that is based upon "Modules" that can be "mixed and matched" to suit the application. Some might believe that a more centralized approach would be best.
When i code i would generally want to have some sort of base design before hand. i would add to the base design as i went along. There are articles out there that show some design patterns, but it is kind of all up to you in the end. But that's just my opinion.
Also, would you mind sharing an example? i am quite interested to see this code style that you fear :P
More importantly, it's usually based on what you are coding. Are you coding games? if so, what components would you need? (Audio, Graphics, Input, etc;).
I'm creating a framework for cross-platform development (kind of like SDL/SFML) that is based upon "Modules" that can be "mixed and matched" to suit the application. Some might believe that a more centralized approach would be best.
When i code i would generally want to have some sort of base design before hand. i would add to the base design as i went along. There are articles out there that show some design patterns, but it is kind of all up to you in the end. But that's just my opinion.
Also, would you mind sharing an example? i am quite interested to see this code style that you fear :P
-
- Chaos Rift Newbie
- Posts: 21
- Joined: Mon Oct 03, 2011 10:58 am
Re: Thirst for knowledge!
Brilliant response and I agree completely, but I would definitely like to see some literature based on the subject .
I'll show you one of my class declarations:
This class uses "entitycell" which is:
I was actually criticized by someone upon showing them these, but they didn't really explain why they despised it! I'm worried I'm not using things to their full potential.
There's also a bad/lazy bit of code in there, which is that my inventory is public because I was too lazy to pass it through a method.
I'll show you one of my class declarations:
Code: Select all
class character
{
private:
int health;
int xpos;
int ypos;
float exactx;
float exacty;
char block;
entitycell ecp;
public:
entitycell inventory[4][7];
character();
void readplayerinfo();
void saveplayerinfo();
void addtoinventory(entitycell toadd);
int checkinvfull();
void saveinv();//writes the inventory to file
void readinv(); //reads the inventory from the file into the array, pretty nifty stuff.
int moveup();
int movedown();
int moveleft();
int moveright();
entitycell checkentity();
int checkstate();
void inittargetblock(char targetblock);
int checkx();
int checky();
int checkhp();
};
Code: Select all
class entitycell// a variable which holds an entity's information!
{
public:
int state; // 0 = nonesolid, 1 = solid
int ecid;
char ecsprite;
int colour;
bool isitem;
entitycell();
void ecellrefresh();
};
There's also a bad/lazy bit of code in there, which is that my inventory is public because I was too lazy to pass it through a method.
-
- Chaos Rift Cool Newbie
- Posts: 78
- Joined: Mon Feb 21, 2011 2:55 am
- Current Project: Aleios Engine
- Favorite Gaming Platforms: PC, Dreamcast
- Programming Language of Choice: C++
- Location: Melbourne, Australia
Re: Thirst for knowledge!
Hmm, i see. Well my first criticism of your character class would be grouping. Its more of an aesthetic thing rather than compiler wise (sort of). For example:
can be shortened to:
also this:
i personally would change it to:
Also, im not sure if checkx, checky, and checkhp are accessors or per update functions. If they are accessors then:
where the first "const" says the returned value will be constant, and the last one basically says "i am not allowed to make changes to *this" (basically you cant edit a member variable)
or if they are per update then why not just:
and stick all that crap in there. I try to minimalize as much as possible.
The rest i would not be able to figure out without first hand knowledge. And if someone says it's crap without explaining why, then (since i am prone to raging) i would tell em to shove it up their ass in specific cases.
I can say with certainty that the code you showed is kind of ugly, however, i have seen worse! MUCH WORSE!
Hell, my code even looks like complete shit at times, but what i do is draw out a couple of rectangles, write down the class name (with relevance to its function).
Then i write what methods and member variables i shall expect it to contain. As shown by Gyro, whiteboards are just legendary for these things.
I am in no way an expert, far from it, but the above is just a small example of how i would structure things. I could post a few bits from my current project, some of it makes me scream when i wake up the next morning (or rather afternoon...)
Code: Select all
int health;
int xpos;
int ypos;
float exactx;
float exacty;
Code: Select all
int health, xpos, ypos;
float exactx, exacty;
Code: Select all
int moveup();
int movedown();
int moveleft();
int moveright()
Code: Select all
int move(int direction);
//or i would do
enum DIRECTION { UP, DOWN, LEFT, RIGHT };
int move(DIRECTION direction);
Code: Select all
const int GetX() const;
const int GetY() const;
const int GetHP() const;
or if they are per update then why not just:
Code: Select all
void Update();
The rest i would not be able to figure out without first hand knowledge. And if someone says it's crap without explaining why, then (since i am prone to raging) i would tell em to shove it up their ass in specific cases.
I can say with certainty that the code you showed is kind of ugly, however, i have seen worse! MUCH WORSE!
Hell, my code even looks like complete shit at times, but what i do is draw out a couple of rectangles, write down the class name (with relevance to its function).
Then i write what methods and member variables i shall expect it to contain. As shown by Gyro, whiteboards are just legendary for these things.
I am in no way an expert, far from it, but the above is just a small example of how i would structure things. I could post a few bits from my current project, some of it makes me scream when i wake up the next morning (or rather afternoon...)
-
- Chaos Rift Newbie
- Posts: 21
- Joined: Mon Oct 03, 2011 10:58 am
Re: Thirst for knowledge!
Some interesting points, I'm never too sure when to make things const, simply because it's unclear (to me) in that example why you're using a constant value either side, as surely these values can't be altered by anything else since they are private anyway and our methods to check what they are merely give us some information.
for example, in my code I'm 99.99% sure that I can't go and do:
player1.checkx() = 1;
because that would be trying to edit a return value, or "the sum" of the method?
I agree and understand with the rest of what you've said, very good CC, thanks!
edit: also, I tabbed out of shopping for whiteboards to read this
for example, in my code I'm 99.99% sure that I can't go and do:
player1.checkx() = 1;
because that would be trying to edit a return value, or "the sum" of the method?
I agree and understand with the rest of what you've said, very good CC, thanks!
edit: also, I tabbed out of shopping for whiteboards to read this
- short
- ES Beta Backer
- Posts: 548
- Joined: Thu Apr 30, 2009 2:22 am
- Current Project: c++, c
- Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
- Programming Language of Choice: c, c++
- Location: Oregon, US
Re: Thirst for knowledge!
By placing the const keyword, you allow the compiler to make certain optimizations, as well as enforcing semantics with code. For example,SPR_Phantom wrote:Some interesting points, I'm never too sure when to make things const, simply because it's unclear (to me) in that example why you're using a constant value either side, as surely these values can't be altered by anything else since they are private anyway and our methods to check what they are merely give us some information.
Code: Select all
const int getX() const
The const after getX() tells the compiler, this method will not modify any member variables of the object (allowing other behind the scenes optimizations to take place).
While it is common to use const exactly at is above, the following is a more concrete example:
Code: Select all
void whatevs()
{
const int RANGE_MAX = 35;
...
RANGE_MAX = 37; // compile error
}
If you don't want a variable to be altered, declare it const.
If you don't want a member function to change any member variables, place the const keyword after the method name (before the curly brace)
Back to the returning a const value. The distinction I made between about disallowing the callee of a function to modify the return value (as an r-value) is pretty complex (imho).
You can never do the following:
Code: Select all
++getX(); // compile error, error C2105: '++' needs l-value
Code: Select all
int value = getX();
++value;
Disclaimer, I've only learned about what an r-value and l-value are recently, through the new C++0x standard, when I was curious about the move-constructor. If someone sees something incorrect call me out, as I'd love to concertize my knowledge of them.
edit: I edited the above, but I'm not sure of a concrete example of how returning const int vs int would yield different results, perhaps it would just help the compiler with some optimizations. I'll post back if I discover anything new.
Last edited by short on Sun Oct 09, 2011 1:05 pm, edited 2 times in total.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
link: https://github.com/bjadamson
-
- Chaos Rift Newbie
- Posts: 21
- Joined: Mon Oct 03, 2011 10:58 am
Re: Thirst for knowledge!
The "concrete" example of const was the one I was familiar with already, however I usually use #define for things like that.
Thanks for explaining it in detail, I can safely know which methods to apply that to and which to not now!
unfortunately I do like to fuck with the return values directly, but isn't that the optimized way of doing things anyway? since if you assigned the return value to a variable first you'd be taking up an extra x bytes of memory?
the const that stops the method itself altering the variable is very nice and I'll add that to all my none side-effect methods!
so yeah I'd love to know if it's more optimized to fuck with your return value or to put it in a box, then fuck with it !
Again I'd love to know where you guys learn design rules like these in the first place, because I was taught there was such a thing as a class, etc and how they work, but never how they should work in relation to what you're doing with them, if you get me.
Thanks for explaining it in detail, I can safely know which methods to apply that to and which to not now!
unfortunately I do like to fuck with the return values directly, but isn't that the optimized way of doing things anyway? since if you assigned the return value to a variable first you'd be taking up an extra x bytes of memory?
the const that stops the method itself altering the variable is very nice and I'll add that to all my none side-effect methods!
so yeah I'd love to know if it's more optimized to fuck with your return value or to put it in a box, then fuck with it !
Again I'd love to know where you guys learn design rules like these in the first place, because I was taught there was such a thing as a class, etc and how they work, but never how they should work in relation to what you're doing with them, if you get me.
- short
- ES Beta Backer
- Posts: 548
- Joined: Thu Apr 30, 2009 2:22 am
- Current Project: c++, c
- Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
- Programming Language of Choice: c, c++
- Location: Oregon, US
Re: Thirst for knowledge!
The return value from the function still needs to be copied out.
It gets "copied out" when you do something like:
or
It's not like your avoiding a copy either way.
It gets "copied out" when you do something like:
Code: Select all
if(getX() > 30)
Code: Select all
int x = getX()
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
link: https://github.com/bjadamson
- szdarkhack
- Chaos Rift Cool Newbie
- Posts: 61
- Joined: Fri May 08, 2009 2:31 am
Re: Thirst for knowledge!
Compilers are smart enough to optimize these copies much better than you could ever achieve in C++, so in my opinion, if you can make the code more clear and readable, do so and the compiler will take care of the rest.SPR_Phantom wrote:unfortunately I do like to fuck with the return values directly, but isn't that the optimized way of doing things anyway? since if you assigned the return value to a variable first you'd be taking up an extra x bytes of memory?
Now, regarding your design issues, i would suggest that you check some nice C++ code and try to see how others are doing things. I don't have any links to share off the top of my head, but i'm sure it won't be too hard to find some. But, at the end of the day, the object oriented paradigm is there to serve YOU, not for you to serve IT. So, if you find that it makes things worse, don't do it. Do what you are more comfortable with to minimize your chances of having to recode something because of faulty design.
Also, a way that i *personally* learned better oop, is by coding in strictly oop languages such as Java or C#, nothing big, just test projects. These languages require oop and you will be "forced" to learn how to do it. Again, this worked for *me*, it might not work for you. I'm just putting it out there.
Keep trying, you'll get the hang of it
-
- Chaos Rift Cool Newbie
- Posts: 78
- Joined: Mon Feb 21, 2011 2:55 am
- Current Project: Aleios Engine
- Favorite Gaming Platforms: PC, Dreamcast
- Programming Language of Choice: C++
- Location: Melbourne, Australia
Re: Thirst for knowledge!
Well, for classes i guess you could look at them like this. First look around you. What do you see? I would have to bet 100% on a computer or laptop. Maybe you have a couch, bed, desk, chair, etc; around you. Think of what we call them ultimately. They are Objects, these objects have certain functions, a chair is for sitting on, a bed for sleeping (sometimes ). OOP or Object Oriented Programming can be used in such a way as this. So let's make a class named Computer. What functions will computer need to do? Well, one i could think of would be to TogglePower. Now for this function i would want some way to track if the power is on or off, so let's make a boolean value named "power". power will not need to be accessed directly by anything else, so let's make it a private member variable. And let's just make an accessor quickly.SPR_Phantom wrote: Again I'd love to know where you guys learn design rules like these in the first place, because I was taught there was such a thing as a class, etc and how they work, but never how they should work in relation to what you're doing with them, if you get me.
Computer.hpp
Code: Select all
#ifndef COMPUTER_H
#define COMPUTER_H
class Computer
{
public:
Computer();
void TogglePower();
const bool GetPowerState() const;
private:
bool power;
};
#endif
Code: Select all
#include "Computer.hpp"
Computer::Computer()
: power(false)
{
}
void Computer::TogglePower()
{
power = !power;
}
const bool Computer::GetPowerState() const
{
return power;
}
Code: Select all
#include "Computer.hpp"
#include <iostream>
int main(int argc, char* argv[])
{
// Don't really need to dynamically allocate in this instance, but meh...
Computer *computer = new Computer();
std::cout << "The current state is: " << computer->GetPowerState() << "\nSetting new State...\n";
computer->TogglePower();
std::cout << "The new state is: " << computer->GetPowerState() << "\n";
delete computer;
// May need, keeps vc++ console up.
std::cin.get();
return 0;
}
-
- Chaos Rift Newbie
- Posts: 21
- Joined: Mon Oct 03, 2011 10:58 am
Re: Thirst for knowledge!
Some good examples there, thanks !
I never thought of using ! before a variable's name to invert it like that, very appropriate!
I'm having a crack at making my program look nice internally before I bind it with lua, if I can get the internals very clear it should be much easier ( I hope ) to implement lua, so here goes :D
I never thought of using ! before a variable's name to invert it like that, very appropriate!
I'm having a crack at making my program look nice internally before I bind it with lua, if I can get the internals very clear it should be much easier ( I hope ) to implement lua, so here goes :D
Re: Thirst for knowledge!
What is this non-sense you've decided to spew, youngster? You claim to be in college at the tender age of 17... Act your age!SPR_Phantom wrote:I was actually criticized by someone upon showing them these, but they didn't really explain why they despised it! I'm worried I'm not using things to their full potential.
[quote="YouTube message TO "SPR_Phantom" - 10/06/'11"]Hello, MaxRavelle.
First off, it looks like you've copied & pasted code you've found off of MSDN (the examples), and have made no attempt to learn them, or apply them in any reasonable sense.
Second off, I'm not sure how you managed to implement that frame limiter (I'll assume you copied someone elses code, or simply their idea), but it is very impressive to me. There are alternatives methods to creating a frame limiter with the console, but that, is a pretty universal approach. I like it.
Third off, you aren't using wrapper functions, which makes reading some of this stuff very difficult. You are using the 'raw' Win32 API, which is fine... But I prefer to create wrapper functions for readability purposes. If nothing else, use a #define macro like you did for the 'W' key (you named it: "Wk").
Fourth off, aside from the fact you have INDEED created a monolithic main.cpp file, the class organization (as you stated before) is horrendous! I do not like it AT all! I do not like how you named things either (that's of no consequence, personal preference).
I found it to be EXTREMELY difficult! To locate and follow stuff. I also noticed soon on that you used a "float" type when you're assigning it "double" values; I simply changed those float's to double's and it worked fine; That may be a difference between the GCC/VS compilers though.
The fact that you have it CONSTANTLY writing to the harddrive is BAD. You do NOT need to do that! It not only will wear out the harddrive faster, but wastes system resources (not that they are really necessary for a project of this magnitude (lack thereof)). Bad habits die hard though.
Fifth off, you are using GetAsyncKeyState instead of using the console's internal buffer to manipulate key input. With how you have this set up, I do not even need the window's focus to play the game!! Select the foreground, like your browser. Let the console over-lap on top of the browser. Press the "W, A, S, D" keys, and see your character move... Disastrous, no?
This is just a basis of ideas (criticism). If you'd like to see some source code, I'd be more than happy to provide some soon. However, I am going to bed soon. I work today from 16:00 to 18:00.
Talk to you later! "[/quote]
... Here is a partial copy of his reply shortly after (I can check my e-mail and post exact time/dates if anyone's interested):
[quote="YouTube message TO "SPR_Phantom" - 10/06/'11"]Thank you for your tips/criticisms, I have not yet had the chance to pick up good habits as this has been my first C++ project this side of 2011 and while I did have to read up again on how to do some of it I in no way stole any of my code or simply copy/pasted.[/quote]
Yet here it is, the same day I offered more explanation, and offered more help, and awaited an eagerness on his behalf or simply interest in the project idea altogether! More lies stacked upon lies! Why must you do so? I do not understand. It is absolutely unnecessary and unreasonable! It is ludicrous, SPR_Phantom. Please don't...
If I have failed to explain myself in depth, then tell me so! So I may try again from another approach, one that you might understand better. Do not thank me for something you do not understand, SPR_Phantom. That only wastes BOTH our time, and creates frustration (as shown). I am fully well aware you have declined any further help, due to some estranged belief that I have attacked you on a personal basis, but I will offer my hand one last time...SPR_Phantom wrote:I was actually criticized by someone upon showing them these, but they didn't really explain why they despised it! I'm worried I'm not using things to their full potential.
Normally I would send this over YouTube, but that's irrelevant to me at this point, as I believe everyone should see this, as everyone who reads it will benefit from it in a positive way, hopefully. I will again explain more and more as to why I disliked the way you went about things in your simple game:
- Monolithic main.cpp
This is a MAJOR design flaw! It is hard to locate specifically what you need. Modifying the existing code-base becomes extremely frustrating, and difficult - Your syntax ("style of writing")
I disagree with how everything was written, at random seeming, pieced together from different sources.
- The macro at the beginning
- The "cls()" function at the end
- The irregular white spacing altogether - The naming of variables, classes, and functions
"entitycell," "ecellrefresh," "ecid" are all hard for me to read - General DESIGN paradigm
This seems to be lacking altogether! I see three monolithic classes: entitycell, area, and character - Reinventing the wheel
You chose to create an ENTIRE class wrapper ("entitycell") dedicated to the console cells (color, position, etc) instead of using what's already there! - Reinventing the wheel x2 (the console IS an array ALREADY!!!)
You implement an ENTIRE (duplicate) array to 'reference' the console within the "area" class - CONSTANT harddrive file writes
There is NO point in continually updating the file every program iteration; This wears down the harddrive more than it needs to be. This also constantly OPENS and CLOSES the file, just asking for a corrupted save file when something malfunctions (power-outage just to name one) - Direct Win32 API calls - UGLY!
Another personal preference, as stated in a YouTube PM once before: Wrapper functions do not only provide an 'easier' and 'more clear' way of calling library functions, but may provide MORE functionality, without constantly repeating code (see: C++ overloaded functions, C++ overloaded operators). - main() function
Disgusting, cluster of unreadable crap! The error checking was fine. The lack of whitespace? NO! The awkward system of arbitrary seeming loops? Disgusting!!! That could've been done so, so!!! Much better!
There were some potential solutions you'd mentioned you could do, over YouTube, such as keeping the GetAsyncKeyState() functions and simply 'working around' them to keep the wretched design that you have set up already (which leads me to believe you know of NO other way to, and are HIDING that fact!). I insisted you learn something new, such as the ReadConsoleInput() API call (among others). It's a SMALL amount of work for the LARGE SCALE amount of benefits you'd reap! There was other stuff, but I'll leave that to YOU to discuss and bring up.
Sorry about all the crap over IRC; I have not been feeling well lately, and honestly, the conversation regarding English was VERY stimulating to me. I should've taken it to a PM, but equally, you (whomever complained) could have squelched me just as easily.