Difference between revisions of "Cogniteam/CodeConvention"
(Created page with "==General OOP principles== * Object-oriented programming [https://en.wikipedia.org/wiki/Object-oriented_programming OOP] * SOLID principles [https://en.wikipedia.org/wiki/SO...") |
|||
| Line 1: | Line 1: | ||
==General OOP principles== | ==General OOP principles== | ||
| + | * Object-oriented programming [https://en.wikipedia.org/wiki/Object-oriented_programming OOP] | ||
| + | * SOLID principles [https://en.wikipedia.org/wiki/SOLID SOLID] | ||
| + | * Software design pattern [https://en.wikipedia.org/wiki/Software_design_pattern Desigh Patterns] | ||
| + | |||
| + | ==Coding style and naming convention== | ||
| + | |||
| + | ===C++ naming conventions=== | ||
| + | |||
| + | {| class="wikitable" | ||
| + | ! Convention name !! Example | ||
| + | |- | ||
| + | | Upper Camel Case || UpperCamelCase | ||
| + | |- | ||
| + | | Lower Camel Case || lowerCamelCase | ||
| + | |- | ||
| + | | Upper Snake Case || UPPER_SNAKE_CASE | ||
| + | |- | ||
| + | | Lower Snake Case || lower_snake_case | ||
| + | |} | ||
| + | |||
| + | {| class="wikitable" style="width: 100%" | ||
| + | |- | ||
| + | ! Component !! Convention !! Example | ||
| + | |- | ||
| + | | Variables || Lower camel case || <syntaxhighlight lang="C++"> | ||
| + | int state_; | ||
| + | MessageType messageType; | ||
| + | |||
| + | uint32_t countOfSomething; | ||
| + | |||
| + | ros::NodeHandle rosNodeHandle; | ||
| + | </syntaxhighlight> | ||
| + | |- | ||
| + | | Methods || Lower camel case || <syntaxhighlight lang="C++"> | ||
| + | void calculate(); | ||
| + | |||
| + | int getCount(); | ||
| + | |||
| + | int processIncomingMessages(); | ||
| + | </syntaxhighlight> | ||
| + | |- | ||
| + | | Member variables || Add '_' suffix to name, '''cannot be public''' || <syntaxhighlight lang="C++"> | ||
| + | int memberVariable_; | ||
| + | |||
| + | std::string name_; | ||
| + | |||
| + | ros::ServiceClient rosServiceClient_; | ||
| + | </syntaxhighlight> | ||
| + | |- | ||
| + | | Class names || Upper camel case || <syntaxhighlight lang="C++"> | ||
| + | class Vector3; | ||
| + | class AgentController; | ||
| + | class MapAligner; | ||
| + | </syntaxhighlight> | ||
| + | |- | ||
| + | | [https://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classes Abstract classes] || Upper camel case<br/>Prefix 'I' for interfaces - pure abstract classes without any implementations<br />Suffix 'Base' for abstract base classes with some implementations || <syntaxhighlight lang="C++"> | ||
| + | class ITextParser; // Pure abstract class - defines only interfaces without any implementations | ||
| + | class IMapFilter; | ||
| + | |||
| + | class TaskBase; // Abstract class with some implementations common to all tasks | ||
| + | class MappingBase; | ||
| + | |||
| + | </syntaxhighlight> | ||
| + | |- | ||
| + | | Namespaces || Lower camel case || <syntaxhighlight lang="C++"> | ||
| + | namespace cognitao_utils { } | ||
| + | |||
| + | namespace cogniteam { | ||
| + | namespace tools { | ||
| + | |||
| + | } /* namespace tools */ | ||
| + | } /* namespace cogniteam */ | ||
| + | </syntaxhighlight> | ||
| + | |- | ||
| + | | Enums || Upper camel case<br />[https://stackoverflow.com/questions/18335861/why-is-enum-class-preferred-over-plain-enum Prefer enum class over regular enums] || MessageTypes, Colors<syntaxhighlight lang="C++"> | ||
| + | enum class MessageTypes { | ||
| + | Single = 1, | ||
| + | MultiPacket = 2, | ||
| + | }; | ||
| + | |||
| + | enum class Colors { | ||
| + | Red = 0x00, | ||
| + | Green = 0x01, | ||
| + | Blue = 0x02 | ||
| + | }; | ||
| + | </syntaxhighlight> | ||
| + | |} | ||
| + | |||
| + | ===Files and folders=== | ||
| + | |||
| + | * Files and packages: | ||
| + | ** upper camel case for class headers and sources (MyClass.h, MyClass.cpp) | ||
| + | ** lower snake case for file containing main method (my_executable.cpp, my_ros_node.cpp, robot_driver_node.cpp) | ||
| + | ** lower snake case for package names (my_package, hamster_driver, elbit_planner) | ||
| + | * '''DON'T USE MACROS''' | ||
| + | * '''DON'T USE DEFINES''' (except header guards) | ||
| + | * Why not? | ||
| + | ** http://www.stroustrup.com/bs_faq2.html#macro | ||
| + | ** [https://git.cogni.io/maytronics/maytronics/snippets/8 Try to debug this] | ||
| + | |||
| + | Related: | ||
| + | * [http://wiki.ros.org/CppStyleGuide ROS C++ style guide] | ||
| + | * [http://wiki.ros.org/ROS/Patterns/Conventions ROS naming convention] | ||
| + | |||
| + | |||
| + | <syntaxhighlight lang="C++"> | ||
| + | /* | ||
| + | * CogniteamClass.h | ||
| + | * | ||
| + | * Created on: Jan 1, 2031 | ||
| + | * Author: John Doe <johndoe@cogniteam.com> | ||
| + | * | ||
| + | * | ||
| + | * Cogniteam LTD CONFIDENTIAL | ||
| + | * | ||
| + | * Unpublished Copyright (c) 2010-2020 Cogniteam, All Rights Reserved. | ||
| + | * | ||
| + | * NOTICE: All information contained herein is, and remains the property | ||
| + | * of Cogniteam. The intellectual and technical concepts contained | ||
| + | * herein are proprietary to Cogniteam and may be covered by Israeli and | ||
| + | * Foreign Patents, patents in process, and are protected by trade secret | ||
| + | * or copyright law. Dissemination of this information or reproduction of | ||
| + | * this material is strictly forbidden unless prior written permission is | ||
| + | * obtained from Cogniteam. Access to the source code contained herein | ||
| + | * is hereby forbidden to anyone except current Cogniteam employees, | ||
| + | * managers or contractors who have executed Confidentiality and | ||
| + | * Non-disclosure agreements explicitly covering such access | ||
| + | * | ||
| + | * The copyright notice above does not evidence any actual or intended | ||
| + | * publication or disclosure of this source code, which includes | ||
| + | * information that is confidential and/or proprietary, and is a trade | ||
| + | * secret, of Cogniteam. ANY REPRODUCTION, MODIFICATION, DISTRIBUTION, | ||
| + | * PUBLIC PERFORMANCE, OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS | ||
| + | * SOURCE CODE WITHOUT THE EXPRESS WRITTEN CONSENT OF Cogniteam IS | ||
| + | * STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL | ||
| + | * TREATIES. THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED | ||
| + | * INFORMATION DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE | ||
| + | * OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, OR SELL ANYTHING | ||
| + | * THAT IT MAY DESCRIBE, IN WHOLE OR IN PART | ||
| + | * | ||
| + | */ | ||
| + | // Maximum 80 characters per line // new line | ||
| + | // new line | ||
| + | // | ||
| + | // Always use header guards for header files | ||
| + | // | ||
| + | #ifndef PATH_TO_FILE_AND_FILE_NAME_ | ||
| + | #define PATH_TO_FILE_AND_FILE_NAME_ | ||
| + | // new line | ||
| + | // new line | ||
| + | // | ||
| + | // Group includes of the same library and separate it using a new line | ||
| + | // Order your include files from low level to higher. | ||
| + | // 1. libstd C headers: <printf.h>, <file.h>, <math.h> | ||
| + | // 2. libstd C++ headers: <fstream>, <thread>, <mutex>, <cmath> | ||
| + | // 4. Other 3rd party includes: <boost/mutex.hpp>, <Qt/QtCore>, <ros/ros.h>, | ||
| + | // <pcl/pcl.h> | ||
| + | // 4. Local includes: <cogniteam/project_name3/SomeClass.h> | ||
| + | // | ||
| + | #include <printf.h> | ||
| + | // new line | ||
| + | #include <iostream> | ||
| + | #include <fstream> | ||
| + | #include <mutex> | ||
| + | // new line | ||
| + | #include <boost/bind.hpp> | ||
| + | #include <boost/thread.hpp> | ||
| + | #include <boost/thread/mutex.hpp> | ||
| + | #include <boost/asio.hpp> | ||
| + | #include <boost/asio/serial_port.hpp> | ||
| + | #include <boost/system/error_code.hpp> | ||
| + | // new line | ||
| + | #include <ros/ros.h> | ||
| + | #include <std_msgs/String.h> | ||
| + | #include <ackermann_msgs/AckermannDriveStamped.h> | ||
| + | // new line | ||
| + | #include <cogniteam/AwesomeClass.h> | ||
| + | #include <cogniteam/project_name3/JustSomeClass.h> | ||
| + | // new line | ||
| + | // new line | ||
| + | // | ||
| + | // Always wrap your code with a namespace | ||
| + | // | ||
| + | namespace cogniteam { | ||
| + | namespace project_name { | ||
| + | // new line | ||
| + | // new line | ||
| + | // Include other namespaces | ||
| + | using namespace std; | ||
| + | using namespace cogniteam::project_name2; | ||
| + | // new line | ||
| + | // new line | ||
| + | /** | ||
| + | * Custom color for... | ||
| + | */ | ||
| + | enum class CogniColor { | ||
| + | Red = 1, | ||
| + | Blue = 2, | ||
| + | Green | ||
| + | }; | ||
| + | // new line | ||
| + | // new line | ||
| + | /** | ||
| + | * High level description of class purposes | ||
| + | * @note Comment using Doxygen's 'Javadoc style' format | ||
| + | * @url http://www.doxygen.nl/manual/docblocks.html | ||
| + | */ | ||
| + | class CogniteamClass : public CogniteamBaseClass { | ||
| + | // Use separate public block for constructors and descructor | ||
| + | public: | ||
| + | |||
| + | /** | ||
| + | * Construct a new Cogniteam Class object | ||
| + | */ | ||
| + | CogniteamClass(); | ||
| + | |||
| + | /** | ||
| + | * Construct a new Cogniteam Class object | ||
| + | * @param obj1 | ||
| + | */ | ||
| + | CogniteamClass(const SomeClass& obj1); | ||
| + | |||
| + | /** | ||
| + | * Copy constructor | ||
| + | * @note Don't forget to implement copy constructor & copy assignment operator | ||
| + | * if you have pointers in your class | ||
| + | * @param obj1 | ||
| + | */ | ||
| + | CogniteamClass(const CogniteamClass& obj1); | ||
| + | |||
| + | /** | ||
| + | * Destroys the Cogniteam Class object | ||
| + | * @note Always declare virtual desctrutor in your classes | ||
| + | */ | ||
| + | virtual ~CogniteamClass(); | ||
| + | |||
| + | public: | ||
| + | |||
| + | /** | ||
| + | * Public type alias for convenient | ||
| + | */ | ||
| + | using Ptr = shared_ptr<CogniteamClass>; | ||
| + | |||
| + | using ConstPtr = shared_ptr<CogniteamClass const>; | ||
| + | |||
| + | public: | ||
| + | |||
| + | // | ||
| + | // Public member methods | ||
| + | // NO PUBLIC VARIABLE ALLOWED - USE GETTERS AND SETTERS | ||
| + | // | ||
| + | // Getter & Setter example for member variable object_: | ||
| + | // | ||
| − | |||
| − | * | + | /** |
| + | * Set the Var object | ||
| + | * @note inline setters & getters | ||
| + | * @note Use const methods for getters | ||
| + | * @note Setters and getters must be as short as possible, ideally, | ||
| + | * one copy assignment and one return: | ||
| + | * @param var | ||
| + | * @return int | ||
| + | */ | ||
| + | inline void setObject(Object& object) { | ||
| + | object_ = object; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Gets the Object object | ||
| + | * @return Object | ||
| + | */ | ||
| + | inline Object getObject() const { | ||
| + | return object_; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * Use prefix T for template parameters (MessageT, ServiceT, PacketT...) | ||
| + | * @tparam ObjectT | ||
| + | * @param object | ||
| + | */ | ||
| + | template <typename ObjectT> | ||
| + | void templateMethod(const ObjectT& object) { | ||
| + | // ... | ||
| + | } | ||
| + | |||
| + | protected: | ||
| + | |||
| + | // | ||
| + | // Protected member methods | ||
| + | // | ||
| + | |||
| + | /** | ||
| + | * Protected method, visible by this and derived classes | ||
| + | * @return int | ||
| + | */ | ||
| + | int protectedMethod(); | ||
| + | |||
| + | protected: | ||
| + | |||
| + | // | ||
| + | // Protected member variables | ||
| + | // | ||
| + | |||
| + | /** | ||
| + | * Protected member variable, visible by this and derived classes | ||
| + | */ | ||
| + | int protectedMemberVariable_ = 0; | ||
| + | |||
| + | private: | ||
| + | |||
| + | // | ||
| + | // Private member methods | ||
| + | // | ||
| − | * | + | /** |
| + | * Runs my algorithm | ||
| + | * @param param1 First parameter | ||
| + | * @param param2 Second parameter | ||
| + | * @param param3 Another parameter | ||
| + | * @return true If success | ||
| + | * @return false If failure | ||
| + | */ | ||
| + | bool runAlgorithm(double param1, double param2, double param3); | ||
| + | /** | ||
| + | * Calculates a number such that... | ||
| + | * @param param1 First param for calculationg | ||
| + | * @return double Calculation result | ||
| + | */ | ||
| + | double calculateNumber(double param1) const; | ||
| − | + | private: | |
| − | + | // | |
| + | // Private member methods | ||
| + | // | ||
| − | + | /** | |
| + | * Const member example, upper case with underscore, place const's first | ||
| + | */ | ||
| + | const string CONST_MEMBER_STRING = "monitor_red"; | ||
| − | + | /** | |
| + | * Private variable, visible by this class only | ||
| + | */ | ||
| + | Object object_; | ||
| − | + | }; | |
| + | // new line | ||
| + | // new line | ||
| + | } /* namespace widgets */ | ||
| + | } /* namespace ocu */ | ||
| + | } /* namespace lynx */ | ||
| + | // new line | ||
| + | // new line | ||
| + | #endif /* PATH_TO_FILE_AND_FILE_NAME_ */ | ||
| + | // new line | ||
| + | </syntaxhighlight> | ||
Revision as of 13:45, 30 December 2019
Contents
General OOP principles
- Object-oriented programming OOP
- SOLID principles SOLID
- Software design pattern Desigh Patterns
Coding style and naming convention
C++ naming conventions
| Convention name | Example |
|---|---|
| Upper Camel Case | UpperCamelCase |
| Lower Camel Case | lowerCamelCase |
| Upper Snake Case | UPPER_SNAKE_CASE |
| Lower Snake Case | lower_snake_case |
| Component | Convention | Example |
|---|---|---|
| Variables | Lower camel case | <syntaxhighlight lang="C++">
int state_; MessageType messageType; uint32_t countOfSomething; ros::NodeHandle rosNodeHandle; </syntaxhighlight> |
| Methods | Lower camel case | <syntaxhighlight lang="C++">
void calculate(); int getCount(); int processIncomingMessages(); </syntaxhighlight> |
| Member variables | Add '_' suffix to name, cannot be public | <syntaxhighlight lang="C++">
int memberVariable_; std::string name_; ros::ServiceClient rosServiceClient_; </syntaxhighlight> |
| Class names | Upper camel case | <syntaxhighlight lang="C++">
class Vector3; class AgentController; class MapAligner; </syntaxhighlight> |
| Abstract classes | Upper camel case Prefix 'I' for interfaces - pure abstract classes without any implementations Suffix 'Base' for abstract base classes with some implementations |
<syntaxhighlight lang="C++">
class ITextParser; // Pure abstract class - defines only interfaces without any implementations class IMapFilter; class TaskBase; // Abstract class with some implementations common to all tasks class MappingBase; </syntaxhighlight> |
| Namespaces | Lower camel case | <syntaxhighlight lang="C++">
namespace cognitao_utils { } namespace cogniteam { namespace tools { } /* namespace tools */ } /* namespace cogniteam */ </syntaxhighlight> |
| Enums | Upper camel case Prefer enum class over regular enums |
MessageTypes, Colors<syntaxhighlight lang="C++">
enum class MessageTypes { Single = 1, MultiPacket = 2, }; enum class Colors { Red = 0x00, Green = 0x01, Blue = 0x02 }; </syntaxhighlight> |
Files and folders
- Files and packages:
- upper camel case for class headers and sources (MyClass.h, MyClass.cpp)
- lower snake case for file containing main method (my_executable.cpp, my_ros_node.cpp, robot_driver_node.cpp)
- lower snake case for package names (my_package, hamster_driver, elbit_planner)
- DON'T USE MACROS
- DON'T USE DEFINES (except header guards)
- Why not?
Related:
<syntaxhighlight lang="C++">
/*
* CogniteamClass.h
*
* Created on: Jan 1, 2031
* Author: John Doe <johndoe@cogniteam.com>
*
*
* Cogniteam LTD CONFIDENTIAL
*
* Unpublished Copyright (c) 2010-2020 Cogniteam, All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property
* of Cogniteam. The intellectual and technical concepts contained
* herein are proprietary to Cogniteam and may be covered by Israeli and
* Foreign Patents, patents in process, and are protected by trade secret
* or copyright law. Dissemination of this information or reproduction of
* this material is strictly forbidden unless prior written permission is
* obtained from Cogniteam. Access to the source code contained herein
* is hereby forbidden to anyone except current Cogniteam employees,
* managers or contractors who have executed Confidentiality and
* Non-disclosure agreements explicitly covering such access
*
* The copyright notice above does not evidence any actual or intended
* publication or disclosure of this source code, which includes
* information that is confidential and/or proprietary, and is a trade
* secret, of Cogniteam. ANY REPRODUCTION, MODIFICATION, DISTRIBUTION,
* PUBLIC PERFORMANCE, OR PUBLIC DISPLAY OF OR THROUGH USE OF THIS
* SOURCE CODE WITHOUT THE EXPRESS WRITTEN CONSENT OF Cogniteam IS
* STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL
* TREATIES. THE RECEIPT OR POSSESSION OF THIS SOURCE CODE AND/OR RELATED
* INFORMATION DOES NOT CONVEY OR IMPLY ANY RIGHTS TO REPRODUCE, DISCLOSE
* OR DISTRIBUTE ITS CONTENTS, OR TO MANUFACTURE, USE, OR SELL ANYTHING
* THAT IT MAY DESCRIBE, IN WHOLE OR IN PART
*
*/
// Maximum 80 characters per line // new line
// new line
// // Always use header guards for header files //
- ifndef PATH_TO_FILE_AND_FILE_NAME_
- define PATH_TO_FILE_AND_FILE_NAME_
// new line
// new line
// // Group includes of the same library and separate it using a new line // Order your include files from low level to higher. // 1. libstd C headers: <printf.h>, <file.h>, <math.h> // 2. libstd C++ headers: <fstream>, <thread>, <mutex>, <cmath> // 4. Other 3rd party includes: <boost/mutex.hpp>, <Qt/QtCore>, <ros/ros.h>, // <pcl/pcl.h> // 4. Local includes: <cogniteam/project_name3/SomeClass.h> //
- include <printf.h>
// new line
- include <iostream>
- include <fstream>
- include <mutex>
// new line
- include <boost/bind.hpp>
- include <boost/thread.hpp>
- include <boost/thread/mutex.hpp>
- include <boost/asio.hpp>
- include <boost/asio/serial_port.hpp>
- include <boost/system/error_code.hpp>
// new line
- include <ros/ros.h>
- include <std_msgs/String.h>
- include <ackermann_msgs/AckermannDriveStamped.h>
// new line
- include <cogniteam/AwesomeClass.h>
- include <cogniteam/project_name3/JustSomeClass.h>
// new line
// new line
// // Always wrap your code with a namespace // namespace cogniteam { namespace project_name {
// new line
// new line
// Include other namespaces using namespace std; using namespace cogniteam::project_name2;
// new line
// new line
/**
* Custom color for... */
enum class CogniColor {
Red = 1, Blue = 2, Green
};
// new line
// new line
/**
* High level description of class purposes * @note Comment using Doxygen's 'Javadoc style' format * @url http://www.doxygen.nl/manual/docblocks.html */
class CogniteamClass : public CogniteamBaseClass {
// Use separate public block for constructors and descructor
public:
/**
* Construct a new Cogniteam Class object
*/
CogniteamClass();
/**
* Construct a new Cogniteam Class object
* @param obj1
*/
CogniteamClass(const SomeClass& obj1);
/**
* Copy constructor
* @note Don't forget to implement copy constructor & copy assignment operator
* if you have pointers in your class
* @param obj1
*/
CogniteamClass(const CogniteamClass& obj1);
/**
* Destroys the Cogniteam Class object
* @note Always declare virtual desctrutor in your classes
*/
virtual ~CogniteamClass();
public:
/**
* Public type alias for convenient
*/
using Ptr = shared_ptr<CogniteamClass>;
using ConstPtr = shared_ptr<CogniteamClass const>;
public:
// // Public member methods // NO PUBLIC VARIABLE ALLOWED - USE GETTERS AND SETTERS // // Getter & Setter example for member variable object_: //
/**
* Set the Var object
* @note inline setters & getters
* @note Use const methods for getters
* @note Setters and getters must be as short as possible, ideally,
* one copy assignment and one return:
* @param var
* @return int
*/
inline void setObject(Object& object) {
object_ = object;
}
/**
* Gets the Object object
* @return Object
*/
inline Object getObject() const {
return object_;
}
/**
* Use prefix T for template parameters (MessageT, ServiceT, PacketT...)
* @tparam ObjectT
* @param object
*/
template <typename ObjectT>
void templateMethod(const ObjectT& object) {
// ...
}
protected:
// // Protected member methods //
/**
* Protected method, visible by this and derived classes
* @return int
*/
int protectedMethod();
protected:
// // Protected member variables //
/**
* Protected member variable, visible by this and derived classes
*/
int protectedMemberVariable_ = 0;
private:
// // Private member methods //
/**
* Runs my algorithm
* @param param1 First parameter
* @param param2 Second parameter
* @param param3 Another parameter
* @return true If success
* @return false If failure
*/
bool runAlgorithm(double param1, double param2, double param3);
/**
* Calculates a number such that...
* @param param1 First param for calculationg
* @return double Calculation result
*/
double calculateNumber(double param1) const;
private:
// // Private member methods //
/**
* Const member example, upper case with underscore, place const's first
*/
const string CONST_MEMBER_STRING = "monitor_red";
/**
* Private variable, visible by this class only
*/
Object object_;
};
// new line
// new line
} /* namespace widgets */ } /* namespace ocu */ } /* namespace lynx */
// new line
// new line
- endif /* PATH_TO_FILE_AND_FILE_NAME_ */
// new line
</syntaxhighlight>