--- auto_car.h -----------------------------------------------
// Includes first
#include <stdio.h>
// Auto name space
namespace Auto {
// Class goes here
}
--- auto_car.h -----------------------------------------------
From this you can see two to three things about my syntax right away. I often add a comment before each line (we'll get more deeply into this a little later), I name my namespaces with a leading capital letter, and I like to put my left bracket at the end of the line instead of the following line.
The braces are probably the thing that will make most discussion here. It's almost religious amongst coders. Either you like it, or you don't. For me, it was a question of getting used to it (I was forced to use it when programming java in university, and since we were programming as a whole group, we had to use the same syntax as far as possible). However, I got to like it and now I never use anything else.
Classes
If we continue building our header file, we'll continue with this:
--- auto_car.h -----------------------------------------------
#ifndef AUTO_CAR_H
#define AUTO_CAR_H
// Includes
#include <stdio.h>
// Auto name space
namespace Auto {
// Class goes here
class Car : public VehicleType {
public:
protected:
private:
};
}
#endif
--- auto_car.h -----------------------------------------------
We'll leave the methods for now, and take a look at the class structure. First of all I've added redundant security by the first two lines and the last. This is made because if vector.h includes math.h and math.h includes vector.h, we have a problem. But you are probably aware of this fact already. How you name these defines is not my problem, but for all defines I use only capital letters.
The naming of the class always starts with a capital letter, and I've placed no prefix on the name (many people use conventions like CCar, I don't). The VehicleType I would normally call Vehicle I guess, but I wanted to show you how I start every new word in a name with a capital letter.
The public: -block is located at the top of the file. This is because then you look into the code, you will most often need the public (sometimes protected) interface, but never the private one. This way you won't need to scroll down a page or five just to find the public block; it's at the top, visible at the very start of the file.
I use the same naming for structs by the way, if I ever use them.
Adding Methods, Member and Parameter Variables
The naming of variables is something which also upsets people, but I think if you follow this method you will never confuse yourself :
--- auto_car.h -----------------------------------------------
#ifndef AUTO_CAR_H
#define AUTO_CAR_H
// Includes
#include <stdio.h>
// Auto name space
namespace Auto {
// Class goes here
class Car : public VehicleType {
public:
const float getSpeed();
void setSpeed(const float pSpeed);
protected:
private:
float mSpeed;
float mSomeVariable;
};
}
#endif
--- auto_car.h -----------------------------------------------
Here you can see how I do it. For member variables, I use the prefix m. For parameters, I use the prefix p. The next letter is a capital one, and the same as every name, every new word within the same variable begins with a capital letter, such as mSomeVariable.
I use m as a prefix no matter where in my class the variable lies. Some people insist on using iVariable or fVariable to define which kind of type the variable is. For instance, iVariable would mean we're editing an integer. But then, if we want to change our type, we will need to rename that variable both in the hader file and the source file. I think that is waste of time and really never gives you any advantage. The naming of the variable could solve this issue. For instance, why would the variable "mMemberName" be an integer? I can see how people argue then it comes to something like "mSpeed". Is that integer or float representation? Well, in most cases it's crystal clear, or you will just have to check the header file.
Every core OOP programmer will probably agree with me that get/set-methods for most variables are a good thing, simply due to the fact that you might want to do more than just change the variable, for instance send a message for an update or similar.
The parameters we've already covered, but I cannot push enough that const is a really good thing. That's really what makes your code easier to use in a greater perspective and makes you find bugs before they appear. Using const correctly takes time to learn, especially with pointers, but it's a bliss then you're used to it, so use it. Now. It's a good standard!
Documenting
The above code would be worth nothing in reuse purposes if we don't comment it. As I think javadoc gives us a really good, standard way of documenting code, I think we should all use it. This is an example of how javadoc works, but it has so much to offer that it would be impossible to cover it all, so to learn more about javadoc how about visiting its homepage? However, here's a demonstration of the (partially limited) way I use it:
--- auto_car.h -----------------------------------------------
#ifndef AUTO_CAR_H
#define AUTO_CAR_H
// Includes
#include <stdio.h>
// Auto name space
namespace Auto {
/**
* Car class. Simple car in auto game :-)
*
* @author Albert "thec" Sandberg
* @version 1.0.0
*/
class Car : public VehicleType {
public:
/**
* Get the speed of the car
*
* @return speed in miles per hour.
*/
const float getSpeed();
/**
* Set the speed of the car
*
* @param pSpeed new speed of the car.
*/
void setSpeed(const float pSpeed);
protected:
private:
// Speed of the car
float mSpeed;
// Extra variables
float mSomeVariable;
};
}
#endif
--- auto_car.h -----------------------------------------------
That's really starting to look like something you could show your mama doesn't it? :-)
Of course, javadoc has syntax for documenting variables, extended information on which variables a method changes and a lot of other stuff. The javadoc syntax has everything you need for your documentation demands. Another very nice thing with javadoc is that doxygen (documentation creation tool for C++) handles javadoc syntax flawless. So you really can have your cake and eat it :-)
How About Other Namings?
First of all, we have enumerations. These are great to use then you have a number of modes and you really don't care about their values, just the names. One example that could be within the public:-scope of the above class:
enum eCarManufacturer {
CM_DODGE,
CM_SAAB,
CM_TOYOTA,
CM_VOLVO,
}
These will be assigned values 0,1,2,3, but you never need to know since all you care about is that none of them have the same value.
Anyway, the "eCarManufacturer" naming with the leading e is nothing that naturally falls into place, it's just something I've discovered to be my best way. However, I see the capital letters of the constant values more or less as defines, and therefore they are capitals all the way.
The prefix CM_ is used because if you have two enums in the same class, you want to be able to enter the enumeration "BLUE" both for a car and a plane, for instance. Anyway, even if conflicts are pretty rare to appear, this is a good principle.
Another thing is constant variables, such as:
static const int staticVariable=42;
I keep as normal (local, in-method) variables. BUT, (as far as I can) I never use globally declared variables like this because it's considered a bad habit and you should really get rid of it. Hence, it doesn't matter how we write it, since we will never do it anyway, right? ;-)
Now we've covered most things you will encounter, I hope. Let's have a look at a source file (.cpp)
Example Of A Source File
Let's get right to it then.
--- auto_car.cpp -----------------------------------------------
// Include header definition
#include "auto_car.h"
// =====================================================
const float Auto::Car::getSpeed() {
// Deaccellerate if brakes are pushed
calculateBreakPower();
// Return speed from superclass
return VehicleType::getSpeed();
}
// =====================================================
void Auto::Car::setSpeed(const float pSpeed) {
// Call superclass setspeed
VehicleType::setSpeed(pSpeed);
// Update car (just as an example)
update();
}
// =====================================================
--- auto_car.cpp -----------------------------------------------
Hard to see in this example, but I really try to document every single line of the source code so that I (and eventually others) will see what I've done. Believe me, the simplest line of code can appear the most confusing if not properly documented a couple of months after you write it.
Many people say I document too much, but my view is that you can never do that too much!
Between the methods in the source file I like to have some kind of gross seperator. But, maybe that's just me.
本文地址:http://com.8s8s.com/it/it21933.htm