Alright so I'm trying to creating something that is sort of like the properties in C# for my classes in C++.
for example. in C# i would do this:
int MaxHP { get; set; }
or, with backing field:
int MaxHP
{
get { return maxHP; }
set { maxHP = value; }
}
However so far with C++, I've only been able to replicate this with:
private:
int maxHP;
int maxEP;
public:
int GetMaxHP() { return maxHP; }
void UpSetMaxHP(int value){ maxHP += value; }
void DownSetMaxHP(int value){ maxHP -= value; }
int GetMaxEP(){ return maxEP; }
void UpSetMaxEP(int value){ maxEP += value; }
void DownSetMaxEP(int value){ maxEP -= value; }
I must be missing something in the way things should be designed. In C# the property would be access like a field. however in C++ I have to do functions which work differently when accessed from other objects.
I guess i could do:
public:
int MaxHP;
But that feels like I am sort of defeating the purpose. So my question is, Am i doing this right or is there a better, proper way of achieving this?
Rather than creating separate getter and setter functions, you can have a function which returns a reference which can be used either way:
public:
int &max_hp() { return maxHP; }
Unlike just delaring maxHP public, this allows you to place a breakpoint to see when the variable is accessed, and if you later want to add conditions or logging you can do so without changing your class interface.
This feature does not exist in C/C++. You could easily argue that it's a defect to be missing but not all languages are equal. The one thing Java has that C# doesn't is singleton object-like enums. It's otherwise, IMO, a bit of a dated language, but it still has one solid feature that's missing in C#.
So what I'm saying is, when you run into these things, often you do find a genuine weakness or a design flaw. It's good to ask if you're just missing something (hence my upvote) but as you learn what strengths and weaknesses different languages have, you'll learn which languages are good for which jobs and perhaps be effective at writing DSLs or language extensions earlier in your career than later.
C/C++ does not support anything like this by default, however it is commonplace to have functions such as int getHP() and void setHP(int) but there is kind of an operator 'hack' to make it function pretty close to how c#'s get/set works. But the code to work around this is very messy and can cause many bugs.
Example (2nd post): http://forums.codeguru.com/showthread.php?459696-GET-SET-in-C
To get rid of getters and setters functions in C++, I have written a simple macro that gets and sets most of data types that I use in my software. Templates also can be useful for that.
For example
#define GET_BOOL(name) bool is##name() const {return name##_;}
#define SET_BOOL(name) void set##name(bool name) {name##_ = name;}
#define GET_SET_BOOL(name) GET_BOOL(name) SET_BOOL(name)
I often see stuff like this:
class SomeClass {
public:
void someMethod();
private:
int someMember;
};
This seems totally unnatural to me (the same applies to case-statements when using switch). I expected something like this, when I started using C++ (it's been a long time since then, but I am still wondering):
class SomeClass {
public:
void someMethod();
private:
int someMember;
};
Is there a funded reason to break (otherwise) consistent indentation rules?
Increasing indentation normally reflects entry to a new nested scope, whereas both access specifiers and switch case statements don't vary the scope (the same is true of labels generally). Access specifiers can be optional in that you may start implementing a class or struct and have all members only need the implied access (i.e. private and public respectively), but then the code evolves and you need to add a specifier for the non-implied-access members: is it really worth having to suddenly change the indentation on all members? Again, there's no nested scope, so I think that would be actively misleading.
If you work on fixed-width terminals and wrap your lines accordingly, reindenting's a pain. But, it is useful to have the access specifiers stand out from the members, which means putting them back to the left somewhere - either in line with the class keyword or part-way there.
Personally, I do this:
class X
{
public:
int member_function()
{
switch (expression)
{
case X:
return 6;
default:
{
int n = get_value() / 6;
return n * n;
}
}
}
private:
int member_variable_;
};
Why do I not indent code for each case further? I can't claim what I do is particularly logical, but factors include:
I don't want to deemphasise the general switch/case indentation, as visually communicating the extent of the switch is important to quickly understanding the code
I'm happy just to put the { and } around existing case code - more like a comment "hey, I need a scope" - rather than feeling compelling to indent everything further, which doesn't make much sense even to me but kind of feels right - I like having the code for each case line up
some compilers do warn if you introduce new variables inside a case statement without introducing a scope, even if there are no cases when the variable is later used potentially uninitialised
I'm an 80-column coder generally, with 4 space indents normally, so being inside a switch - and thus obviously a function - means remaining columns are valuable.
Same for class/struct:
I want to scan the left column and quickly find the end of the class, or easily count the small classes on screen or in a printout; access specifiers at exactly the same indentation level deemphasise the class keyword, but it does help to have them visually distinct from the members (if the class/struct is more than a few lines, I also add a blank line beforehand)
I don't want to change existing class/struct member indentation when I introduce a private or protected specifier
In conclusion: lots of small factors go into developing people's indentation preferences, and if you want to be a C++ programmer in a corporate environment - especially a contractor - you just have to go with the flow and be able to change your own style sometimes too (e.g. I'm stuck in camelCaseLand right now, with public member variables starting with an uppercase letter - yikes!). Don't sweat it - it's not worth it.
The access specifiers are really just labels (as in those used by goto). People generally don't indent labels, or outdent them one level with respect to the surrounding code. So I would say this is not inconsistent at all.
The Standard also uses this style for access specifiers. Example from Chapter 10, paragraph 2:
class Base {
public:
int a, b, c;
};
Imagine such a class definition:
class SomeClass {
void ImplicitlyPrivateMethod();
public:
void someMethod();
private:
int someMember;
};
With the style of indentation you propose, one would need to change this into
class SomeClass {
void ImplicitlyPrivateMethod();
public:
void someMethod();
private:
int someMember;
};
(which looks not so nice to many people, especially if the "implicit" section is long enough).
I personally prefer half-indentation of such specifiers:
class SomeClass {
void ImplicitlyPrivateMethod();
public:
void someMethod();
private:
int someMember;
};
But this is a matter of personal taste.
As with many other things, it is important not to mistake the rule with the purpose. The purpose of indentation is making code clearer and easier to read by providing an extra visual hint on what belongs where. Now, in the particular cases you mention, together with namespaces, in many cases the extra indentation does not help in readability. The cases in a switch can be understood as if-elses, where you would not add the extra indentation. The cases are block delimiters similar to the curly braces.
switch ( var ) {
case 1: // if ( var == 1 ) {
code;
case 2: // } else if ( var == 2 ) {
code;
}
At class level, access modifiers can be considered to be block delimiters at the same level that the class braces. Adding an extra level of indentation does not make the code clearer:
class test {
public:
void foo();
private:
int member;
};
The same way goes with namespaces, where some people avoid indenting the whole namespace level. In all three cases, there is no clear advantage in adding the extra indentation and if you abide to short code lines (80/100 characters) and big enough indentation levels (8 or even 4 characters) then there might be an advantage to not indenting.
Personally, I never indent case or accessor modifiers, in the case of namespaces, it depends... a namespace that covers the whole source file will most probably not be indented, while namespaces that only take part of the source file will be indented --the rationale is that in the former case it adds no actual value, while in the second it does.
Two possible reasons:
that's how Bjarne Stroustrup indents them in his books
most text editors indent them that way automatically
Because public and private are labels which don't introduce a new scope, I prefer not to give them any special indentation, thus:
class foo {
public:
void something();
void something_else();
private:
int top_secret;
};
This way, the consistent indentation rule is "indentation equals scope".
It's all about scoping and grouping of branches. If these are not affected, then do not add an indentation level.
Take for instance the following:
if( test == 1 ) {
action1( );
} else if( test == 2 ) {
action2( );
} else {
action3( );
}
Take note of the levels of the statement blocks. Now re-write it as a case statement with indented cases:
switch( test ) {
case 1:
action1( );
break;
case 2:
action2( );
break;
default:
action3( );
break;
}
This does the exact same functionally, yet the indentations don't match of my actions. And I think it is this inconsistency that finally made me change to dropping the extra spurious indentation. (Even though I don't mind the half-indenting proposed by others, mind you.)
There are very few access modifier lines per class, and most editors color modifiers differently from everything else. They stand out plenty on their own, so adding tabs is unnecessary.
As mentioned earlier (though argued for non-indented access modifiers), access modifiers form logical blocks. While these are at the same level as the class braces, they are special.
Thus it's useful to have indentation to clearly show where each block starts and ends.
I personally think it makes the code clearer. Others will dissagree.
This is a rather subjective question.
Most editors indent them automatically. For me, I leave them as they are in small classes or small files or short switch statements, but for long ones or a long file with many long switch statements I use more indentation for easier readability.
I sometimes do this which I feel is as old style:
Class CClass
{
CClass();
~CClass();
Public:
int a;
Private:
int b;
};
CClass::CClass
{
TODO code;
}
This sometimes makes it easier when a file may contain more than 20 or 50 functions, so you can easily spot the beginning of every function.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I come from a the Objective-C and Cocoa world where there are lots of conventions and many people will say it makes your code beautiful!
Now programming in C++ I cannot find a good document like this one for C++.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html
Standard C++ probably does not have something like above but I hope I can stick to some other SDK or APIs (like Microsoft's(?),etc) conventions.
I hope you can provide me with some links.
Do whatever you want as long as its minimal, consistent, and doesn't break any rules.
Personally, I find the Boost style easiest; it matches the standard library (giving a uniform look to code) and is simple. I personally tack on m and p prefixes to members and parameters, respectively, giving:
#ifndef NAMESPACE_NAMES_THEN_PRIMARY_CLASS_OR_FUNCTION_THEN_HPP
#define NAMESPACE_NAMES_THEN_PRIMARY_CLASS_OR_FUNCTION_THEN_HPP
#include <boost/headers/go/first>
#include <boost/in_alphabetical/order>
#include <then_standard_headers>
#include <in_alphabetical_order>
#include "then/any/detail/headers"
#include "in/alphabetical/order"
#include "then/any/remaining/headers/in"
// (you'll never guess)
#include "alphabetical/order/duh"
#define NAMESPACE_NAMES_THEN_MACRO_NAME(pMacroNames) ARE_ALL_CAPS
namespace lowercase_identifers
{
class separated_by_underscores
{
public:
void because_underscores_are() const
{
volatile int mostLikeSpaces = 0; // but local names are condensed
while (!mostLikeSpaces)
single_statements(); // don't need braces
for (size_t i = 0; i < 100; ++i)
{
but_multiple(i);
statements_do();
}
}
const complex_type& value() const
{
return mValue; // no conflict with value here
}
void value(const complex_type& pValue)
{
mValue = pValue ; // or here
}
protected:
// the more public it is, the more important it is,
// so order: public on top, then protected then private
template <typename Template, typename Parameters>
void are_upper_camel_case()
{
// gman was here
}
private:
complex_type mValue;
};
}
#endif
That.
(And like I've said in comments, do not adopt the Google Style Guide for your code, unless it's for something as inconsequential as naming convention.)
There are probably as many naming conventions as there are individuals, the debate being as endless (and sterile) as to which brace style to use and so forth.
So I'll have 2 advices:
be consistent within a project
don't use reserved identifiers (anything with two underscores or beginning with an underscore followed by an uppercase letter)
The rest is up to you.
I actually often use Java style: PascalCase for type names, camelCase for functions and variables, CAPITAL_WORDS for preprocessor macros. I prefer that over the Boost/STL conventions because you don't have to suffix types with _type. E.g.
Size size();
instead of
size_type size(); // I don't like suffixes
This has the additional benefit that the StackOverflow code formatter recognizes Size as a type name ;-)
We follow the guidelines listed on this page: C++ Programming Style Guidelines
I'd also recommend you read The Elements of C++ Style by Misfeldt et al, which is quite an excellent book on this topic.
For what it is worth, Bjarne Stroustrup, the original author of C++ has his own favorite style, described here: http://www.stroustrup.com/bs_faq2.html
While many people will suggest more or less strict Hungarian notation variants (scary!), for naming suggestions I'd suggest you take a look at Google C++ Coding Guidelines. This may well be not the most popular naming conventions, but at least it's fairly complete. Apart from sound naming conventions, there's some useful guidelines there, however much of it should be taken with a grain of salt (exception ban for example, and the tendency to keep away from modern C++ coding style).
Although personally I like the extreme low-tech convention style of STL and Boost ;).
There are many different sytles/conventions that people use when coding C++. For example, some people prefer separating words using capitals (myVar or MyVar), or using underscores (my_var). Typically, variables that use underscores are in all lowercase (from my experience).
There is also a coding style called hungarian, which I believe is used by microsoft. I personally believe that it is a waste of time, but it may prove useful. This is were variable names are given short prefixes such as i, or f to hint the variables type. For example: int iVarname, char* strVarname.
It is accepted that you end a struct/class name with _t, to differentiate it from a variable name. E.g.:
class cat_t {
...
};
cat_t myCat;
It is also generally accepted to add a affix to indicate pointers, such as pVariable or variable_p.
In all, there really isn't any single standard, but many. The choices you make about naming your variables doesn't matter, so long as it is understandable, and above all, consistent. Consistency, consistency, CONSISTENCY! (try typing that thrice!)
And if all else fails, google it.
consistency and readability (self-documenting code) are important. some clues (such as case) can and should be used to avoid collisions, and to indicate whether an instance is required.
one of the best practices i got into was the use of code formatters (astyle and uncrustify are 2 examples). code formatters can destroy your code formatting - configure the formatter, and let it do its job. seriously, forget about manual formatting and get into the practice of using them. they will save a ton of time.
as mentioned, be very descriptive with naming. also, be very specific with scoping (class types/data/namespaces/anonymous namespaces). in general, i really like much of java's common written form - that is a good reference and similar to c++.
as for specific appearance/naming, this is a small sample similar to what i use (variables/arguments are lowerCamel and this only demonstrates a portion of the language's features):
/** MYC_BEGIN_FILE_ID::FD_Directory_nanotimer_FN_nanotimer_hpp_::MYC_BEGIN_FILE_DIR::Directory/nanotimer::MYC_BEGIN_FILE_FILE::nanotimer.hpp::Copyright... */
#ifndef FD_Directory_nanotimer_FN_nanotimer_hpp_
#define FD_Directory_nanotimer_FN_nanotimer_hpp_
/* typical commentary omitted -- comments detail notations/conventions. also, no defines/macros other than header guards */
namespace NamespaceName {
/* types prefixed with 't_' */
class t_nanotimer : public t_base_timer {
/* private types */
class t_thing {
/*...*/
};
public:
/* public types */
typedef uint64_t t_nanosecond;
/* factory initializers -- UpperCamel */
t_nanotimer* WithFloat(const float& arg);
/* public/protected class interface -- UpperCamel */
static float Uptime();
protected:
/* static class data -- UpperCamel -- accessors, if needed, use Get/Set prefix */
static const t_spoke Spoke;
public:
/* enums in interface are labeled as static class data */
enum { Granularity = 4 };
public:
/* construction/destruction -- always use proper initialization list */
explicit t_nanotimer(t_init);
explicit t_nanotimer(const float& arg);
virtual ~t_nanotimer();
/*
public and protected instance methods -- lowercaseCamel()
- booleans prefer is/has
- accessors use the form: getVariable() setVariable().
const-correctness is important
*/
const void* address() const;
virtual uint64_t hashCode() const;
protected:
/* interfaces/implementation of base pure virtuals (assume this was pure virtual in t_base_timer) */
virtual bool hasExpired() const;
private:
/* private methods and private static data */
void invalidate();
private:
/*
instance variables
- i tend to use underscore suffix, but d_ (for example) is another good alternative
- note redundancy in visibility
*/
t_thing ivar_;
private:
/* prohibited stuff */
explicit t_nanotimer();
explicit t_nanotimer(const int&);
};
} /* << NamespaceName */
/* i often add a multiple include else block here, preferring package-style inclusions */
#endif /* MYC_END_FILE::FD_Directory_nanotimer_FN_nanotimer_hpp_ */
It really doesn't matter. Just make sure you name your variables and functions descriptively. Also be consistent.
Nowt worse than seeing code like this:
int anInt; // Great name for a variable there ...
int myVar = Func( anInt ); // And on this line a great name for a function and myVar
// lacks the consistency already, poorly, laid out!
Edit: As pointed out by my commenter that consistency needs to be maintained across an entire team. As such it doesn't matter WHAT method you chose, as long as that consistency is maintained. There is no right or wrong method, however. Every team I've worked in has had different ideas and I've adapted to those.
not nearly as concise as the link you provided: but the following chapter 14 - 24 may help :) hehe
ref: http://www.amazon.com/Coding-Standards-Rules-Guidelines-Practices/dp/0321113586/ref=sr_1_1?ie=UTF8&s=books&qid=1284443869&sr=8-1-catcorr
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What are your favorite C++ coding style idioms? I'm asking about style or coding typography such as where you put curly braces, are there spaces after keywords, the size of indents, etc. This is opposed to best-practices or requirements such as always deleting arrays with delete[].
Here is an example of one of my favorites: In C++ Class initializers, we put the separators at the front of the line, rather than the back. This makes it easier to keep this up to date. It also means that source code control diffs between versions are cleaner.
TextFileProcessor::
TextFileProcessor( class ConstStringFinder& theConstStringFinder )
: TextFileProcessor_Base( theConstStringFinder )
, m_ThreadHandle ( NULL )
, m_startNLSearch ( 0 )
, m_endNLSearch ( 0 )
, m_LineEndGetIdx ( 0 )
, m_LineEndPutIdx ( 0 )
, m_LineEnds ( new const void*[ sc_LineEndSize ] )
{
;
}
RAII: Resource Acquisition Is Initialization
RAII may be the most important idiom. It is the idea that resources should be mapped to objects, so that their lifetimes are managed automatically according to the scope in which those objects are declared.
For example, if a file handle was declared on the stack, it should be implicitly closed once we return from the function (or loop, or whichever scope it was declared inside). If a dynamic memory allocation was allocated as a member of a class, it should be implicitly freed when that class instance is destroyed. And so on. Every kind of resource—memory allocations, file handles, database connections, sockets, and any other kind of resource that has to be acquired and released—should be wrapped inside such a RAII class, whose lifetime is determined by the scope in which it was declared.
One major advantage of this is that C++ guarantees that destructors are called when an object goes out of scope, regardless of how control is leaving that scope. Even if an exception is thrown, all local objects will go out of scope, and so their associated resources will get cleaned up.
void foo() {
std::fstream file("bar.txt"); // open a file "bar.txt"
if (rand() % 2) {
// if this exception is thrown, we leave the function, and so
// file's destructor is called, which closes the file handle.
throw std::exception();
}
// if the exception is not called, we leave the function normally, and so
// again, file's destructor is called, which closes the file handle.
}
Regardless of how we leave the function, and of what happens after the file is opened, we don't need to explicitly close the file, or handle exceptions (e.g. try-finally) within that function. Instead, the file gets cleaned up because it is tied to a local object that gets destroyed when it goes out of scope.
RAII is also less-commonly known as SBRM (Scope-Bound Resource Management).
See also:
ScopeGuard allows code to "automatically invoke an 'undo' operation .. in the event that an exception is thrown."
When creating enumerations, put them in a namespace so that you can access them with a meaningful name:
namespace EntityType {
enum Enum {
Ground = 0,
Human,
Aerial,
Total
};
}
void foo(EntityType::Enum entityType)
{
if (entityType == EntityType::Ground) {
/*code*/
}
}
EDIT: However, this technique has become obsolete in C++11. Scoped enumeration (declared with enum class or enum struct) should be used instead: it is more type-safe, concise, and flexible. With old-style enumerations the values are placed in the outer scope. With new-style enumeration they are placed within the scope of the enum class name.
Previous example rewritten using scoped enumeration (also known as strongly typed enumeration):
enum class EntityType {
Ground = 0,
Human,
Aerial,
Total
};
void foo(EntityType entityType)
{
if (entityType == EntityType::Ground) {
/*code*/
}
}
There are other significant benefits from using scoped enumerations: absence of implicit cast, possible forward declaration, and ability to use custom underlying type (not the default int).
Copy-swap
The copy-swap idiom provides exception-safe copying. It requires that a correct copy ctor and swap are implemented.
struct String {
String(String const& other);
String& operator=(String copy) { // passed by value
copy.swap(*this); // nothrow swap
return *this; // old resources now in copy, released in its dtor
}
void swap(String& other) throw() {
using std::swap; // enable ADL, defaulting to std::swap
swap(data_members, other.data_members);
}
private:
Various data_members;
};
void swap(String& a, String& b) { // provide non-member for ADL
a.swap(b);
}
You can also implement the swap method with ADL (Argument Dependent Lookup) directly.
This idiom is important because it handles self-assignment[1], makes the strong exception guarantee[2], and is often very easy to write.
[1] Even though self-assignment isn't handled as efficiently as possible, it's supposed to be rare, so if it never happens, this is actually faster.
[2] If any exception is thrown, the state of the object (*this) is not modified.
CRTP: Curiously Recurring Template Pattern
CRTP happens when you pass a class as a template parameter to its base class:
template<class Derived>
struct BaseCRTP {};
struct Example : BaseCRTP<Example> {};
Within the base class, it can get ahold of the derived instance, complete with the derived type, simply by casting (either static_cast or dynamic_cast work):
template<class Derived>
struct BaseCRTP {
void call_foo() {
Derived& self = *static_cast<Derived*>(this);
self.foo();
}
};
struct Example : BaseCRTP<Example> {
void foo() { cout << "foo()\n"; }
};
In effect, call_foo has been injected into the derived class with full access to the derived class's members.
Feel free to edit and add specific examples of use, possibly to other SO posts.
pImpl: Pointer-to-Implementation
The pImpl idiom is a very useful way to decouple the interface of a class from its implementation.
Normally, a class definition must contain member variables as well as methods, which may expose too much information. For example, a member variable may be of a type defined in a header that we don't wish to include everywhere.
The windows.h header is a prime example here. We may wish to wrap a HANDLE or another Win32 type inside a class, but we can't put a HANDLE in the class definition without having to include windows.h everywhere the class is used.
The solution then is to create a Private IMPLementation or Pointer-to-IMPLementation of the class, and let the public implementation store only a pointer to the private one, and forward all member methods.
For example:
class private_foo; // a forward declaration a pointer may be used
// foo.h
class foo {
public:
foo();
~foo();
void bar();
private:
private_foo* pImpl;
};
// foo.cpp
#include whichever header defines the types T and U
// define the private implementation class
class private_foo {
public:
void bar() { /*...*/ }
private:
T member1;
U member2;
};
// fill in the public interface function definitions:
foo::foo() : pImpl(new private_foo()) {}
foo::~foo() { delete pImpl; }
void foo::bar() { pImpl->bar(); }
The implementation of foo is now decoupled from its public interface, so that
it can use members and types from other headers without requiring these dependencies to be present when the class is used, and
the implementation can be modified without forcing a recompile of the code that uses the class.
Users of the class simply include the header, which contains nothing specific about the implementation of the class. All implementation details are contained inside foo.cpp.
I like lining up code/initializations in 'columns'... Proves very useful when editing with a 'column' mode capable editor and also seems to be a lot easier for me to read...
int myVar = 1; // comment 1
int myLongerVar = 200; // comment 2
MyStruct arrayOfMyStruct[] =
{
// Name, timeout, valid
{"A string", 1000, true }, // Comment 1
{"Another string", 2000, false }, // Comment 2
{"Yet another string", 11111000, false }, // Comment 3
{NULL, 5, true }, // Comment 4
};
In contrast, the same code not indented and formatted as above would appear... (A little harder to read to my eyes)
int myVar = 1; // comment 1
int myLongerVar = 200; // comment 2
MyStruct arrayOfMyStruct[] =
{
// Name, timeout, valid
{"A string", 1000, true},// Comment 1
{"Another string", 2000, false }, // Comment 2
{"Yet another string", 11111000,false}, // Comment 3
{NULL, 5, true }, // Comment 4
};
Public Top - Private Down
A seemingly small optimization, but ever since I switched to this convention, I have a way more fun time to grasp my classes, especially after I haven't looked at them for 42 years.
Having a consistent member visibility, going from points of frequent interest down to the boring stuff, is extremely helpful, especially when the code ought to be self-documenting.
(sidenote for qt-users: slots come before signals because they should be callable like non-slot member functions, and apart from their slottyness be indistinguishable from non-slots)
Public, protected, private
then Factory, ctor, dtor, copying, swapping
then the class' Interface
At the very last, in a seperate private: section, comes the data (ideally only an impl-pointer).
This rule also helps a ton if you have problems keeping your class declaration uncluttered.
class Widget : public Purple {
public:
// Factory methods.
Widget FromRadians (float);
Widget FromDegrees (float);
// Ctors, rule of three, swap
Widget();
Widget (Widget const&);
Widget &operator = (Widget const &);
void swap (Widget &) throw();
// Member methods.
float area() const;
// in case of qt {{
public slots:
void invalidateBlackHole();
signals:
void areaChanged (float);
// }}
protected:
// same as public, but for protected members
private:
// same as public, but for private members
private:
// data
float widgetness_;
bool isMale_;
};
In if statements, when there are difficult conditions, you can clearly show which level each condition is using indentation.
if ( ( (var1A == var2A)
|| (var1B == var2B))
&& ( (var1C == var2C)
|| (var1D == var2D)))
{
// do something
}
re: ididak
I fix code that breaks long statements into too many short lines.
Let's face it: it's not the 90's any more.
If your company can't afford widescreen LCDs for its coders, you need to get a better job :)
Compile-time polymorphism
(Also known as syntactic polymorphism and static polymorphism, contrast with runtime polymorphism.)
With template functions, one can write code that relies on type constructors and call signatures of families of parametrized types, without having to introduce a common base class.
In the book Elements of Programming, the authors refer to this treatment of types as abstract genera. With concepts one can specify the requirements on such type parameters, though C++ doesn't mandate such specifications.
Two simple examples:
#include <stdexcept>
template <typename T>
T twice(T n) {
return 2 * n;
}
InIt find(InIt f, InIt l,
typename std::iterator_traits<InIt>::reference v)
{
while (f != l && *f != v)
++f;
return f;
}
int main(int argc, char* argv[]) {
if (6 != twice(3))
throw std::logic_error("3 x 2 = 6");
int const nums[] = { 1, 2, 3 };
if (nums + 4 != find(nums, nums + 4, 42))
throw std::logic_error("42 should not have been found.");
return 0;
}
One can call twice with any regular type that has a binary * operator defined. Similarly, one can call find() with any types that are comparable and that model Input Iterator. One set of code operates similarly on different types, with no shared base classes in sight.
Of course, what's really going on here is that it's the same source code being expanded into various type-specific functions at template instantiation time, each with separate generated machine code. Accommodating the same set of types without templates would have required either 1) separate hand-written functions with specific signatures, or 2) runtime polymorphism through virtual functions.
No favorites but I will fix code that has:
tabs - causes misalignment in many IDEs and code review tools, because they don't always agree on tab at mod 8 spaces.
lines longer than 80 columns - let's face it, shorter lines are more readable. My brain can parse most coding conventions, as long as the lines are short.
lines with trailing whitespaces - git will complain about it as whitespace errors, which show up as red blobs in diffs, which is annoying.
Here is a one-liner to find the offending files:
git grep -I -E '<tab>|.{81,}| *$' | cut -f1 -d: | sort -u
where <tab> is the tab character (POSIX regexp doesn't do \t)
if/while/for parenthesized expression(s) WITH a space separator
if (expression) // preferred - if keyword sticks out more
vs.
if(expression) // looks too much like a void function call
I guess this implies that I like my function calls to NOT have a space separator
foo(parm1, parm2);
After working with someone who was partly blind - and at his request - I switched to using many more spaces. I didn't like it at the time, but now I prefer it. Off the top of my head, the only place where there isn't whitespace between identifiers and keywords and whatnot is after a function name and before the following parentheses.
void foo( int a, int b )
{
int c = a + ( a * ( a * b ) );
if ( c > 12 )
c += 9;
return foo( 2, c );
}
Template and Hook
This is a way to handle as much as possible in a framework and give a door or hook for customization by users of a framework. Also known as Hotspot and Template Method.
class Class {
void PrintInvoice(); // Called Template (boilerplate) which uses CalcRate()
virtual void CalcRate() = 0; // Called Hook
}
class SubClass : public Class {
virtual void CalcRate(); // Customized method
}
Described by Wolfgang Pree in his book Design Patterns for Object-Oriented Software Development.
I don't know if it qualifies as an idiom, exactly, but quite a bit of heavy-duty template programming depends (often heavily) on SFINAE (substitution failure is not an error). A couple of the answers to a previous question have examples.
I really like putting a small statement on the same line as an if
int myFunc(int x) {
if(x >20) return -1;
//do other stuff ....
}
Not sure if this counts as an idiom, but I tend to use doxygen-style inline comments even when the project isn't -yet- using doxygen...
bool MyObjects::isUpToSomething() ///< Is my object up to something
(aside. my comments are not usually quite that lame.)
It's useful to put function names on a new line, so you can grep like
grep -R '^fun_name' .
for them. I've seen that style used for a loads of GNU projects and like it:
static void
fun_name (int a, int b) {
/* ... */
}
Document the return values on the function line, so they are very easy to find.
int function(void) /* return 1 on success, 0 on failure */
{
return 1;
};
Write each method or function argument on a separate line such that it can be easily commented.
int ReturnMaxValue(
int* inputList, /* the list of integer values from which to get the maximum */
long size, /* count of the number of integer values in inputList */
char* extraArgs /* additional arguments that a caller can provide. */
)
I'd suggest PIMPL or as James Coplien originally called it "Handle Body".
This idiom allows you to completely decouple interface from implementation. When working on the rewrite and re-release of a major CORBA middleware component, this idiom was used to completely decouple the API from the implementation.
This practically eliminated any possibility reverse engineering.
An excellent resource for C++ idioms is James Coplien's excellent book "Advanced C++ Programming Styles and Idioms". Highly recommended!
Edit: As pointed out below by Neil, this book is quite out of date with many of his recommendations actually being incorporated into the C++ standard itself. However, I still find it to be a source of useful info, esp. in the form of his PLoP paper on C++ idioms where many idioms were recast into patterm form.
I always nitpick and edit the following:
Superfluous newlines
No newline at EOF
I usually stick to KNF described in *BSD STYLE(9)
I tend to put an else on all of my ifs.
if (condition)
{
complicated code goes here
}
else
{
/* This is a comment as to why the else path isn't significant */
}
Even though it annoys my coworkers.
You can tell at a glance, that I considered the else case during coding.