Coding Guidelines

All class names for the QGroundControl project should have the prefix QGC in front of their name. This helps avoiding name conflicts with other libraries and ensures a consistent presentation of the classes in our library.
Use one header and one source file per class and give the same name for the files the as for the class.

Documentation

  • Good description of the class in the header file (you can even use images if useful)
  • You can structure class members with multiple public/protected/private keywords
  • As for C: Only @brief descriptions in header file, full documentation in implementation

Some useful hints for good C++ programming

This list should give some hints where to put your attention while coding if your new to C++. It is in no way complete and if something is missing feel free to extend the list:

  • Try to use references ('&') as much as possible instead of pointers ('*'). Especially when a function depends on an object as input.
  • Use the C++ casts: 'static_cast<int>(variableName)' instead of '(int)variableName'
  • There is really rarely a reason to pass an object as function argument - use a reference or pointer to it instead.
  • Use const as much as possible, this avoids mistakes and helps the compiler to optimize the code.
    • When an argument is not changed by a function, define the argument as const:
      void aFunction(const PxClass &rInput)
    • When a member function in a class does not change any member variables of its class, define the function as const:
      void aFunction(void) const
    • When you return a reference or pointer to internal data that must not be changed from outside, define the return value of the function as const:
      const PxData *aFunction(void)
  • Try to avoid pointer arithmetic, this makes it often impossible for the compiler to further optimize your code.
  • If an object is only needed localy, create it on the local stack:
    PxClass class(args);  //NOT Java-like PxClass *class = new PxClass(args);

    This has the advantage that the destructor is called automatically when the function exits and no slow memory allocation and deallocation is necessary.

  • When defining variables of classes always take care that the compiler wont do unnecessary work. There is a big difference between these 4 possible definitions considering performance (from best to worst):
    const PxMatrix3x3 &mat(mat2 * mat3);
    PxMatrix3x3 mat(mat2 * mat3);
    PxMatrix3x3 mat = mat2 * mat3;
    PxMatrix3x3 mat = PxMatrix3x3(mat2 * mat3);

    In every case (mat2 * mat3) results in a temporary PxMatrix3x3 object. In the first line a constant reference is initialized to the temporary object, which does not cost anything, its just syntax. But this works only for const references (i.e. you can use this kind of expression for storing temporary results). In the second line the copy constructor of PxMatrix3x3 is called with the temporary result of (mat2 * mat3), in many cases this is optimized so that no copying is necessary (the result of mat2*mat3 is written directly to the local position of mat in the stack). The third and fourth lines show bad definitions: In both cases the standard constructor on the left-hand-side is called, and (third line) the temporary result is copied or (fourth line) the copy constructor is called and then all data is copied. Good compilers can avoid some copying, but especially when non-trivial constructors are used there is always unnecessary copying of data and if the constructors are complex (with database access or similar slow operations) the whole process takes considerable time to run.

Code Example for C++ code

This page shows an example of a documented class.

PxExample.h

/*=====================================================================
 
QGroundControl Open Source Ground Control Station
 
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 
This file is part of the QGROUNDCONTROL project
 
    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
 
======================================================================*/
 
/**
 * @file
 *   @brief Definition of the class PxExample.
 *
 *   @author FirstName LastName <email@example.com>
 *
 */
 
/** @addtogroup code_examples */
/*@{*/
 
 
#ifndef _DOXYGEN_EXAMPLE_H_
#define _DOXYGEN_EXAMPLE_H_
 
#include <QObject>
 
/**
 * @brief Brief description of this class
 *
 * More detailed description of this class.
 *
 */
class PxExample
{
public:
	/** @brief Standard constructor */
	PxExample(void);
	/** @brief Copy constructor */
	PxExample(const PxExample &rExample);
	/** @brief Destructor */
	~PxExample(void) { }
 
public:
	/** @brief Brief description of somePublicFunction */
	bool somePublicFunction(int iCount, const PxExample &rOtherExample) const;
 
public:
	/** @name Name of the Group
	 * You can also group functions. This is the Description of the Group.
	 */
	/*@{*/
	/** @brief Brief Description */
	void someGrouppedFunction1(void);
	/** @brief Brief Description */
	void someGrouppedFunction2(void);
	/*@}*/
 
private:
	/** @brief Brief description of somePrivateFunction */
	void somePrivateFunction(void);
 
private:
	bool m_bMemberVariable1;	///< Description of m_bMemberVariable1
	int m_iMemberVariable2;		///< Description of m_iMemberVariable2
};
 
#endif //_DOXYGEN_EXAMPLE_H_
 
/*@}*/

PxExample.cc

/*=====================================================================
 
QGroundControl Open Source Ground Control Station
 
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 
This file is part of the QGROUNDCONTROL project
 
    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
 
======================================================================*/
 
/**
 * @file
 *   @brief Implementation of the class PxExample.
 *
 *   @author FirstName LastName <email@example.com>
 *
 */
 
#include "PxExample.h"
 
PxExample::PxExample(void)
: m_bMemberVariable1(false),
  m_iMemberVariable2(0)
{
}
 
PxExample::PxExample(const PxExample &rExample)
: m_bMemberVariable1(rExample.m_bMemberVariable1),
  m_iMemberVariable2(rExample.m_iMemberVariable2)
{
}
 
/**
 * @param iCount			Description of the parameter iCount
 * @param rOtherExample		Description of the parameter rOtherExample
 *
 * @return Description of what the function returns
 *
 * Here comes the detailed description of this function.
 *
 * Try to give an example how to use this function whenever possible:
 *
 * @code
 * PxExample example1;
 * PxExample example2;
 * example1.somePublicFunction(example2);
 * @endcode
 */
bool PxExample::somePublicFunction(int iCount, const PxExample &rOtherExample) const
{
	return true;
}
 
/**
 * Here comes the detailed description of this function.
 *
 * For class internal function no usage examples have to be given.
 */
void PxExample::somePrivateFunction(void)
{
	return;
}