google code style note
/************** header file ****************/
// 1, define guards to prevent multiple inclusion
#ifndef PROJECT_PATH_FILE_H_
#define PROJECT_PATH_FILE_H_
//......
#endif // PROJECT_PATH_FILE_H_
// 2, minimize the header file you need to include in your header file
// use forward declaration
class File;
//but in cc file, you should include the header file
//3, use inline function only when they are small
//4, use -inl.h
#include "inline-inl.h"
//5, when defining function, first inputs, then outputs
//6, use standard order
//i.e if your-project/src/base/loggin.h, in logging.cc
#include "base/logging.h"
#include <sys/types.h>//c system file
#include <vector>//c++ system file
#include "other-libraries.h"
#include "other-project-header.h"
/******** scoping ************/
//7, using namespace
//unnamed namespace
//only used in .c file
namespace {
enum{kUnused, kEOF, kError};
bool atEOF(){ return pos_ == kEOF } //use our namespace's EOF
}
//named namespace wrap the entire source file
//in the .h file
namespace a{ class A; } //forward declearation of a::A
namespace mynamespace{
class myClass{
public:
void Foo();
};
}
//in the .cc file
namespace mynamespace{
void myClass::Foo()
{
//.....
}
}
using namespace foo; //IS forbidden!!!!!!!!!
using ::foo::bar; //okay
//namespace alias
namespace f = ::foo::bar;
// 8, do not make nested classes public unless they are part of the interface
class Foo{
private:
class Bar{
};
}
// 9, prefer nonmember function within a namespace or static
//member functions to global functions
//10, place a functions variable in the narrowest scope
//initialize it in the declaration
int j = g(); //good
//if the variable is object
Foo f;
for(int i = 0; i < 10000; ++i){ //here use ++i instead of i++
f.doSomething(i);
}
// 11, static or global variables of class are forbidden
static const char a[10]; //allowed
static string a; //disallowed!!!!!
static int array[10]; //allowed
static vector<int> array(10); //disallowed!!!!
/***************** class ************************/
// 12, if your object requires non-trivial initialization, consider
// having an explicit Init()
class A{
public:
A(){
Init();
}
private:
Init();
};
//13, please define define a default constructor
// however If your class inherits from an existing class but you add no new member var
// you are not required to have a default constructor.
//14, use explicit for constructor with one argument
//copy constructors are exceptions
//classes intended to be transparent wrappers are exceptions
class A{
public:
A();
explicit A(int a); //avoid implicit convertion
};
//15, provide copy only when necessary
// otherwise disable them (make them private)
#define DISALLOW_COPY_AND_ADDIGN(Typename) \
Typename(const Typename& ); \
void operator=(const Typename& )
// in class
class Foo{
public:
Foo(int f);
~Foo();
private:
DISALLOW_COPY_AND_ADDIGN(Foo);
};
//16, use struct only for passive objects carrying data
//17, composition is often more appropriate than inheritance
// all inheritance should be public ("is-a case")
// limit the use of protected
//18, we allow multiple inheritance only when at most one of the base
//classes has an implementation
//19, interface suffix
//when it meets: a) pure virtual
// b) not have non=static data members
// c) not have constructors defined
// d) if a subclass, its superclass should satisfy these conditions
//20, dont overload operators except in rare special circumstances
// in particular, operator= is insidious
operator<<(ostream&, const T&); //is acceptable
//21, make data member private
// exception: static const data
class Foo{
public:
int foo();
private:
int foo_;
};
//22, declaration order
class Foo{
public:
typedef int size; enum{ red, black };
Foo();
~Foo();
//methods
int get(); static int getS();
protected:
private:
int val_; //data member
friend class Bar;
//disallow copy macro
};
//23, prefer small and focused functions
//if the function exceeds about 40 lines, think about breaking it