Jump to content
  • Advertisement
Sign in to follow this  
TIMPAN

What is good code ?

This topic is 4617 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well, over the years :2 years or really 1,5 years, I have been coding in C++ without any other influences of other programming language, but something fubar is about with C++ latly, ah umm well to me it is, but I cant really put my finger on it. So I might as well say it even if it sounds strange. Well the goal is simple really I want to write what the majorty thinks as good code ? is it like the standard ? well what is the standard way of doing things. Well as I know Classes is a big thing with c++ and this is how I use em pretty much. Well lets say I wanna make a Player class. class Player { public: Player() short getAmmo() { return ammo; } void setAmmo(); private: char name [23]; short ammo; }; Well its pretty simple class, anything strange ? Can OOP do anything for me here ? Better way ? A more OOP way ? OOP is object oriented programming huh ? so I wanna reuse as much as possible huh ? Tell me who real programmers code in C++ and how I can do it will coding with the WINAPI with windows and such, any comman places you use OOP in the WINAPI ? or in the games you program. Well, ah I better sum this up, Give good OOP examples and why, Strong sides of c++, and oh yeah, what is good coding. Please explain =) A sleepy progger will thank you !

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by TIMPAN
Well the goal is simple really I want to write what the majorty thinks as good code ? is it like the standard ? well what is the standard way of doing things.
How many C++ programmers does it take to screw in a lightbulb?
100, 1 to do it and 99 to tell the first one how he'd do it faster and better.

There really isn't a standard coding technque, it's just something you grok. There's good helpers, like Code Complete, Effectice C++ or The Pragmatic Programmer, but good coding is something you learn by doing and by reading other people's code.

For your example, this is how I would do it.

class CPlayer {
public:
CPlayer() {;}
~CPlayer {;}
virtual void Update() {;}
virtual void Draw() {:}
}

class CHumanPlayer : public CPlayer
{
etc.
}

Class CComputerPlayer : public CPlayer
{
etc.
}


This way, I can use a CPlayer* to point to either CComputerPlayer or CHumanPlayer and treat all my actors as a single type, instead of handling all the different instances of that class.

On a side note, I really have to get back to coding with people, all my examples aren't very helpful to anyone but myself. [smile]

Share this post


Link to post
Share on other sites
OOP is not the only paradigm available to you in C++. OOP isn't necessarily the best paradigm for all situations. So-called pure OOP isn't necessarily better than a somewhat less "pure" variation. It's all up to you.

C++ is a multi-paradigm language. You are absolutely required to have some procedural code (the entry point), but with a little work you can use any paradigm you want. C++ has some constructs that cater to OOP, but that does not mean you should use them in every situation. For instance, what is the point of the get/set methods in the code you posted? You do not always have to go "pure" OO, and it's not necessary all the time. What's wrong with exposing the variable itself in this case? Hell, what's wrong with making your player object POD?

Keep in mind that even the STL uses functional concepts in a number of places. OO is not the only way.

OOP coders can go off the deep end sometimes. You can make your code "more OO" if you never want to get anything done and apply the paradigm far beyond its uses. To be honest, there is no point in encapsulating your entire game in a class. Subtract 50 points if you plan on using singletons as fancy "OO" globals.

What is "good" code is entirely subjective, but to me it's code that's consistent throughout in style, has meaningful variable and function names, and uses the paradigm appropriate to the problem. Are you really going to implement an enormous State/StateManager class system when a simple switch would suffice? Sometimes "pure OO" isn't the best solution. Use what works best for you and for the specific problem you're solving.

Share this post


Link to post
Share on other sites
I think bigger program benefit more from it. An enemy class might be a better example, where the constructor takes care of initilizing everything for each enemy. There would be a heck of a lot more stuff in that player class if it was in a real game.

Share this post


Link to post
Share on other sites
The problem with having a class with nothing but accessors and mutators is that you may as well make its instance members public, which is almost as bad as using exclusively global variables.

Share this post


Link to post
Share on other sites
Ahh yes the replys softens up my mind but it still bothers me.


what is the point of the get/set methods in the code you posted?
[/QUOTE]

Hehe sorry I was watching Wrath lands video tutorials, classes and how he did it
took over my mind =), but still a class is an object and tht player was (even though its easyness) could have been a object for a player in a shooting-bottles game ( easy one without score and such stuff ), But OO cant really do anything here can it ? in this case give this info ?

But lets say we wanna have three diffrent enemies we'd dirive them from a mother enemey, with only the basics like health and state and such, the others might have fire, water, etc as an element. But that is Polymorhpism ? But that is a part of OO ? isent it.


Keep in mind that even the STL uses functional concepts in a number of places. OO is not the only way.
[/QUOTE]

Okay I need a deep in on that, what is Functional vs OO in general coding lingo?



there is no point in encapsulating your entire game in a class. Subtract 50 points if you plan on using singletons as fancy "OO" globals.
[/QUOTE]

Ohh no, hehe never would I do that, Classes are good imo since they keep function to where the belong just like a index would to a book, so classes is OO
or is there better ways of structuring functions and keeping an eye on where-goes-where ?, Well, Singletons, never learnd so much about them hell I can even do one, is it right that the only allow one instance of the class ( the singletone base ) ? Like a const int Value; then ? or something ... Well okay there is no way I am using them anyways so you dont have to be afraid of that.


Are you really going to implement an enormous State/StateManager class system when a simple switch would suffice?
[/QUOTE]

Well I am not sure I know what your talking about since I have never really seen a State/StateManager but I guess I build a Class with bools and such to control and observ on how the player is progressing in my game. Well I see your point, but this is whats freaky.

int choice = 0;

while( !choice == "1" || !choice == "2" )
{

cout << " Enter a number ?" << endl;
cin >> choice;

}

switch(choice)
{

case 1: cout << " option 1 " << endl; break;

case 2: cout << " option 2 " << endl; break;


}

// an so it goes on ---


this is pretty freaky for me to write, obvious its in a Win32 Console,but lets say its Doom 4(hehe) and the out putting is nice and such, using all kind of new things, would this code exist in this shape in a Doom 4 menu if they wanted to have this kind of effect, either 1 or 2 ( yeah its a long shot ), I think the would have ran it through alot of more OO ways even though the switch would have been nice ? dont you ?

ayh that is fuzzy, I write like that when I dont have the Devil of OO on my shoulder.

ah ya,

When making for example a class and creating int's and short's in the class you not make get/set ? umm thats pretty much wasting c++ ? is it more OO to make one member that handles all when it comes to settting and getting ?

[Edited by - TIMPAN on December 28, 2005 10:56:17 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by TIMPAN
But lets say we wanna have three diffrent enemies we'd dirive them from a mother enemey, with only the basics like health and state and such, the others might have fire, water, etc as an element. But that is Polymorhpism ? But that is a part of OO ? isent it.

That's inheritance, and yes, it is an OO concept. In that case, OO is useful, but that doesn't mean you have to go overboard with accessors when they're not necessary.

Quote:
Original post by TIMPAN
Okay I need a deep in on that, what is Functional vs OO in general coding lingo?

"Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions." Functional and OO paradigms are not necessarily mutually exclusive. Functional even expands on OO in a sense, treating functions as objects.

Quote:
Original post by TIMPAN
Ohh no, hehe never would I do that, Classes are good imo since they keep function to where the belong just like a index would to a book, so classes is OO
or is there better ways of structuring functions and keeping an eye on where-goes-where ?

Namespaces aren't a bad idea. Abusing classes by creating a single instance (or no instance if you make everything static) just to organize functions doesn't make sense when you can use namespaces.

Quote:
Original post by TIMPAN
int choice = 0;

while( !choice == "1" || !choice == "2" )
{

cout << " Enter a number ?" << endl;
cin >> choice;

}

switch(choice)
{

case 1: cout << " option 1 " << endl; break;

case 2: cout << " option 2 " << endl; break;


}

// an so it goes on ---

Now you're worrying me. For one, !choice == "1" will not do what you expect. With a bit of problem solving you can also clean that up and avoid having to check against each case to terminate the loop.


int choice = 0;

loop:
switch(choice)
{
case 1:
std::cout << "Option 1" << std::endl;
break;
case 2:
std::cout << "Option 2" << std::endl;
break;
default:
std::cout << "Enter a number: " << std::endl;
std::cin >> choice;
goto loop;
}

You could even throw a termination variable in there if you're a goto-phobe just to avoid that, but I don't see the point other than the obvious mass hysteria.

Quote:
Original post by TIMPAN
this is pretty freaky for me to write, I dont know if it should but hey lets throw away two thing, obvious its in a Win32 Console, lets say its Doom 4(hehe) and the out putting is nice and such, using all kind of new things, would this code exist in this shape in a Doom 4 menu if they wanted to have this kind of effect, either 1 or 2 ( yeah its a long shot ), I think the would have ran it through alot of more OO ways even though the switch would have been nice ? dont you ?

They would have likely set up a State and StateManager system, with the menu classes and a game class inheriting from State and some sort of stack-based switching system, though there are myriad ways to do this.

Quote:
Original post by TIMPAN
When making for example a class and creating int's and short's in the class you not make get/set ? umm thats pretty much wasting c++ ? is it more OO to make one member that handles all when it comes to settting and getting ?

Just because C++ supports it doesn't mean that you should use it. You will incur no penalties for not using it. Sometimes it's just not appropriate. Some variables don't need getters/setters. If your get and set functions don't actually do anything other than pass the variable around, what's the advantage over accessing it directly? There is none, unless you want to keep track of how many times the variable is accessed or do some sort of processing when it's read or written.

Share this post


Link to post
Share on other sites
The best way to learn good coding practices is to work hands-on in several large code bases. If you've been programming for 2 years, I'd say you're about 8 years away from mastery, so you've got lots of time! (given the rule of thumb that you have to do something for 10 years before you achieve mastery).

In my mind, good code is marked by the following criteria (in no particular order):

* Works, even under stress
* Has been in production for at least a year (i e, all the bad bugs are out)
* Can be extended/developed without too much moaning
* Has sufficient high-level documentation ("this is how these things go together")
* Has sufficient unit tests to allow a new developer to be effective
* Does what it needs to without wasting machine resources

You can write good code in a single style -- say, procedural only, or micro-objects only, or abstract-interfaces only, or generative templates only. But in reality, it's easier, and works better, if you choose the right tool for the task.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ra
OOP is not the only paradigm available to you in C++. OOP isn't necessarily the best paradigm for all situations. So-called pure OOP isn't necessarily better than a somewhat less "pure" variation. It's all up to you.


+1. I would even argue that "pure" any-paradigm (OO, functional, imperative...) is *rarely if ever* ideal.

Quote:
C++ is a multi-paradigm language. You are absolutely required to have some procedural code (the entry point), but with a little work you can use any paradigm you want.


Even supposed "pure OO" languages tend to make a bit of the mess of the entry point IMX :) Anyway, the multi-paradigm-ness of C++ is one of its saving graces. (But note that Python is multi-paradigm as well, and generally much easier to work with ;) )

Anyway, people have some *very strange* ideas about what "OOP" is out there. A get/set pair that does no checks is effectively *worse* than a raw data member; the only benefit you get is that you have designed ahead for using a function call that might be more elaborated upon later, versus the drawbacks:

- You design ahead for, etc. Experience shows that people often don't get around to adding anything significant in the way of checking to the mutator, and hardly ever add anything to the accessor. So it's just extra work.
- You lie to yourself about the encapsulation; access isn't any more restricted than it was before, and clients still end up thinking about the object as a holder for that data member.
- More often than not, you repeat common bits of manipulation code throughout the code base.

I'm going to say something profound, yet stunningly obvious now.

OOP is about giving objects functionality.

That means real functionality rather than just bundling things together. If you just want to bundle things together, then just use a struct (or if it's several things of the same type, consider one of the standard library containers) and let them all be. Otherwise, you want the object's member functions to do useful things - tasks that you can assign names to; tasks that users of the object commonly expect to get done; tasks that make sense for the logical abstraction of the object.

Oh, and before I forget, don't use character arrays to represent textual data (unless you have a specific reason that you want data of a specific length). Use std::string instead. And don't worry about the types of numeric values; as a rough guideline use int (for integers) and double (for floating point) by default, until you have a good reason to change. Saving two bytes of RAM on a machine with a gig of the stuff is not a good reason.

And use initializer lists for constructor parameters where appropriate.


#include <string>
#include <iostream>
class Player {
// Stuff before the first 'public:'/'protected:'/'private:' label
// is implicitly private. I prefer to take advantage of this...
std::string name;
int ammo;
public:
Player(const std::string& name, int ammo) : name(name), ammo(ammo) {}
// Examples of functions that *do something*:
bool fire(const Player& target) {
if (!ammo) return false; // out of ammo.
--ammo;
target.getHit();
return true; // Otherwise, fire a shot and indicate that we did.
}
void getHit() {
std::cout << name << " says, 'Ouch, that hurts!'" << endl;
}
};

Share this post


Link to post
Share on other sites

scary =)

int choice = 0;

while( !choice == "1" || !choice == "2" )
{

cout << " Enter a number ?" << endl;
cin >> choice;

}

switch(choice)
{

case 1: cout << " option 1 " << endl; break;

case 2: cout << " option 2 " << endl; break;


}


sorry it was meant to be

int choice = 0;

while( choice != "1" || !choice != "2" )
{

cout << " Enter a number ?" << endl;
cin >> choice;

}

switch(choice)
{

case 1: cout << " option 1 " << endl; break;

case 2: cout << " option 2 " << endl; break;


}

Thanks Ra, you seems to have shed enough light on me for today, but I guess I will still have questions. Well, I guess it all depends on the people who will be look at the code later on or on the coders that will continue on the code, I guess thats why its so important to be able to name all these ways of doing things so people know what you intend or what you have done.

<QUOTE> <- whatever it is oki =)
They would have likely set up a State and StateManager system, with the menu classes and a game class inheriting from State and some sort of stack-based switching system, though there are myriad ways to do this.
</QUOTE>

hehe, Why would anyone use a stack as a switch ? That is if a stack to you is the same to me. I mean those you can pop ( commnly word for it ) hehe =)

<QUOTE>
* Works, even under stress
* Has been in production for at least a year (i e, all the bad bugs are out)
* Can be extended/developed without too much moaning
* Has sufficient high-level documentation ("this is how these things go together")
* Has sufficient unit tests to allow a new developer to be effective
* Does what it needs to without wasting machine resources
</QUOTE>

That reply was very nice hplus, very good. I guess I can develop some outlines for myself to squint around in my own skill level. I must say its a very difuse thing OO, but I guess it comes with experiance just as you said .

<QUOTE> Zahlman

OOP is about giving objects functionality.

That means real functionality rather than just bundling things together. If you just want to bundle things together, then just use a struct (or if it's several things of the same type, consider one of the standard library containers) and let them all be. Otherwise, you want the object's member functions to do useful things - tasks that you can assign names to; tasks that users of the object commonly expect to get done; tasks that make sense for the logical abstraction of the object.

Oh, and before I forget, don't use character arrays to represent textual data (unless you have a specific reason that you want data of a specific length). Use std::string instead. And don't worry about the types of numeric values; as a rough guideline use int (for integers) and double (for floating point) by default, until you have a good reason to change. Saving two bytes of RAM on a machine with a gig of the stuff is not a good reason.

And use initializer lists for constructor parameters where appropriate.



#include <string>

#include <iostream>

class Player {

// Stuff before the first 'public:'/'protected:'/'private:' label

// is implicitly private. I prefer to take advantage of this...

std::string name;

int ammo;

public:

Player(const std::string& name, int ammo) : name(name), ammo(ammo) {}

// Examples of functions that *do something*:

bool fire(const Player& target) {

if (!ammo) return false; // out of ammo.

--ammo;

target.getHit();

return true; // Otherwise, fire a shot and indicate that we did.

}

void getHit() {

std::cout << name << " says, 'Ouch, that hurts!'" << endl;

}

};

</QUOTE>


most excllent reply, like that you put forward your opionion about OOP + the codie =), it seems to be good anyways, there is no thoughts about what it does.
I can also see what your are sayinh about acessing variables through function calls // Get/Set why it is a bad thing.


Thanks all gamedev'ers

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!