1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
|
==========================
Killbots C++ Style Guide
==========================
*******************************************************************************
Indentation
*******************************************************************************
Structural indentation is done with tabs. Formatting is done with spaces. All
code having the same nested depth has the same number of tabs. This separates
meaning from presentation.
Tabwidth is a matter of personal preference. If the above is followed source is
tabwidth independent.
Ensure your editor doesn't do automatic conversion from spaces to tabs, as this
will break things.
Labels (public, private, goto, case, etc.) do not get indented.
Empty lines do not get indentation. In fact, no lines should have trailing
whitespace.
If a pair of parentheses span multiple lines, the closing parenthesis should be
indented (with spaces) to appear in the same column as the opening parenthesis.
Examples:
-------------------------------------------------------------------------------
bool Killbots::Engine::cellIsValid( const QPoint & cell ) const
{
____return ( 0 <= cell.x()
____.........&& cell.x() < m_rules->columns()
____.........&& 0 <= cell.y()
____.........&& cell.y() < m_rules->rows()
____.......);
}
-------------------------------------------------------------------------------
namespace Killbots
{
____class RenderPrivate
____{
____public:
________RenderPrivate()
________..:.m_svgRenderer(),
________....m_pixmapCache("killbots-cache"),
________....m_cursors(),
________....m_hasBeenLoaded( false )
________{};
-------------------------------------------------------------------------------
____if ( m_rulesetChanged )
____{
________if ( ! m_engine->gameHasStarted() ||
________.....KMessageBox::questionYesNo( this,
________.................................i18n("A new ruleset has been selected, but there is already a game in progress."),
________.................................i18n("Rule Set Changed"),
________.................................KGuiItem( i18n("Continue Current Game") ),
________.................................KGuiItem( i18n("Start a New Game") )
________...............................) == KMessageBox::No
________...)
________{
-------------------------------------------------------------------------------
*******************************************************************************
Braces
*******************************************************************************
Opening and closing braces are always on a new line.
For loop or conditional statements, braces can be omitted if the block is a
single-line statement and the conditional fits on a single line. If braces are
used in one block of an if-elseif-else statement, they should be used in the
other blocks even if those blocks are a single line.
Blocks never appear on the same line as the loop/conditional, even if braces
aren't used.
Empty blocks are represented on a single line as '{}'
Examples:
-------------------------------------------------------------------------------
void Killbots::Engine::refreshSpriteMap()
{
m_spriteMap.clear();
for (Sprite * bot : std::as_const(m_bots))
m_spriteMap.insert( bot->gridPos(), bot );
for (Sprite * junkheap : std::as_const(m_junkheaps))
m_spriteMap.insert( junkheap->gridPos(), junkheap );
}
-------------------------------------------------------------------------------
if ( m_rules->pushableJunkheaps() != Ruleset::None && cellIsValid( nextCell ) )
{
if ( spriteTypeAt( nextCell ) == NoSprite )
return true;
else if ( spriteTypeAt( nextCell ) == Junkheap )
return m_rules->pushableJunkheaps() == Ruleset::Many && canPushJunkheap( m_spriteMap.value( nextCell ), direction );
else
return m_rules->squaskKillsEnabled();
}
else
{
return false;
}
-------------------------------------------------------------------------------
while ( m_rulesetMap.contains( name ) )
name += '_';
-------------------------------------------------------------------------------
*******************************************************************************
Whitespace
*******************************************************************************
Lines should generally be kept to less than 100 characters, but don't make code
uglier just to avoid width.
Two empty lines should be used to separate function definitions.
Within a block, empty lines may be used to break up unrelated lines, but never
more than one.
No space appears between the function name and the opening bracket.
A single space appears between the loop/conditional statement name and the
opening bracket.
Padding spaces appear inside of all parentheses, unless the parentheses are
empty or contain only a string literal.
Binary operators are separated from their operands with a single space. Unary
operators are not.
Pointer and reference symbols have a space on either side.
No padding spaces appear inside angle brackets when using template functions
or classes.
No space appears between a label and the following colon.
No whitespace should appear inside Qt's SIGNAL and SLOT macros.
*******************************************************************************
Indentifiers
*******************************************************************************
All identifiers should use camel case.
Classnames and namespaces begin with uppercase letters. All other identifiers
begin with lowercase letters.
Class data members are prefixed with 'm_', unless they are public KConfigXT
widgets, in which case, they are prefixed with 'kfcg_'.
Indentifiers should favour descriptiveness over brevity. Single letter
variables are acceptable only for iterators or coordinates.
All indentifiers should use American English spelling. (Comments can be in your
choice of English.)
Examples:
-------------------------------------------------------------------------------
namespace Killbots
{
class Ruleset;
class RulesetSelector : public QWidget
{
Q_OBJECT
public: // functions
explicit RulesetSelector( QWidget * parent = 0 );
virtual ~RulesetSelector();
public: // data members
KLineEdit * kcfg_Ruleset;
private: // functions
void findRulesets();
private Q_SLOTS:
void selectionChanged( QString rulesetName );
private: // data members
QListWidget * m_listWidget;
QLabel * m_author;
QLabel * m_authorContact;
QLabel * m_description;
QMap< QString, Ruleset * > m_rulesetMap;
};
}
-------------------------------------------------------------------------------
*******************************************************************************
Comments
*******************************************************************************
Feel free to comment as much as possible.
Comments should describe the purpose of logic or give background details not
obvious from the code. Comments should not describe what the code is doing,
unless the code is extremely dense (in which case the code should probably be
rewritten/refactored anyway).
Comments appear on the line before the code it is commenting on.
Use '/**/' for comments longer than 3 lines.
*******************************************************************************
Class Definitions
*******************************************************************************
Classes should be given simple names and placed inside the Killbots namespace
instead of adding a prefix. (i.e. Killbots::MainWindow instead of
KillbotsMainWindow)
No inline function definitions in the header, even if they are a single
statement. Same goes for constructors.
Define destructors even if they're empty.
Class definitions should be layed out in the following order.
public: // types
public: // functions
public Q_SLOTS:
public: // data members
Q_SIGNALS:
protected: // types
protected: // functions
protected Q_SLOTS:
protected: // data members
private: // types
private: // functions
private Q_SLOTS:
private: // data members
*******************************************************************************
Includes
*******************************************************************************
Include guards are of the form NAMESPACE_CLASSNAME_H.
Group includes in the following order with blank lines in between:
File's own header
Killbots headers
KDE headers
Qt headers
Inside of groups, sort includes alphabetically.
Use the "new" style includes with directory names where appropriate
Forward declare whenever possible in headers.
moc includes appear at the bottom of the source file.
Examples:
-------------------------------------------------------------------------------
#ifndef KILLBOTS_RULESETSELECTOR_H
#define KILLBOTS_RULESETSELECTOR_H
class KLineEdit;
#include <QtCore/QMap>
class QLabel;
class QListWidget;
#include <QWidget>
namespace Killbots
{
class Ruleset;
-------------------------------------------------------------------------------
#include "rulesetselector.h"
#include "ruleset.h"
#include "settings.h"
#include <KDE/KDebug>
#include <KDE/KDialog>
#include <KDE/KLineEdit>
#include <KDE/KLocalizedString>
#include <KDE/KStandardDirs>
#include <QLabel>
#include <QListWidget>
-------------------------------------------------------------------------------
*******************************************************************************
Miscellaneous
*******************************************************************************
It is generally preferred that functions have a single return statement, but
multiple returns statements are exceptable if a single return would make the
code more complicated.
Use the "Q_UNUSED" macro on unused function parameters.
Use "static_cast<>" instead of the C or C++ style type casts when casting
pointers.
When converting one type to another use C++ or constructor style casts. For
example, use "int()" to convert floating types to integers.
Make sure code passes all the English Breakfast Network checks.
|