The basic specification of Linux·C++ code cleanliness

1. Good Naming

Source code is more for developers to read than for compilers to compile, so source code should have good readability. Good naming is a key factor in making your code as readable as possible for others.

Specifically: source code files, namespaces, classes, templates, functions, parameters, variable names, constant names, etc. should all have meaningful and expressive names.

If you're having trouble coming up with appropriate names for variables, classes, or functions, it's likely an indication of some difficulty or design flaw in your code, and it's time to find and address the root cause of the naming difficulty.

Below are specific suggestions for good naming.
1.1. The name should be self-commenting

That is, there is no need for comments to explain the meaning of the name, and you can understand its purpose by seeing the name.

Bad naming examples:

    uint unm;
    bool flag;
    QList<Costomers> list;
    QString data;

Good naming examples:

    uint numberOfPerson;
    bool isChanged;
    QList<Costomers> costomersList;
    QString personalInformation;

Care should be taken not to use names that are too verbose. Shorter and less descriptive names can be used if the context of the variable is clear. For example:

    struct personInfo
    {
        QString nameOfPerson;
        int ageOfPerson;  
    };

Knowing that this is a structure of information about people, it is redundant to use person in variables, which can be written as:

    struct personInfo
    {
        QString name;
        int age;  
    };

(Just an illustrative example, most people don't write code like this...)
1.2, domain-driven design

That is, components, classes, functions, etc. are named after the concepts and elements of the application domain.

For example:

    class QueryStudentCourseSelection
    {
    public:
        Student identityStudent(const int StudentID);
        CourseList getAllSelectedCourseList(const int StudentID);
        Teacher viewTeacherInformation(std::string teacherName);
    };

This is a class related to student selection, and various definitions in it use elements related to the field of education, which makes the functions of this class quite easy to understand.
1.3, layered structure

For a hierarchical structure, the deeper the hierarchy, the more specific the name.

    class CarFactory
    {
    public:
        CarFactory();
        void produceCars(int number);
    };
     
    class GreenCarFactory : public CarFactory
    {
    public:
        GreenCarFactory();
        void produceGreenCars(int number);    
    };

1.4. Avoid redundant names

Such names should be avoided:

    class Movie
    {
    private:
        QString stringTitle;
    };

The movie name is a string, and the string in front of the name is obviously redundant.
1.5. Avoid using obscure abbreviations

When writing variable names, you should use full words instead of abbreviations, which will increase the readability of the code.

    QString PWD;//not recommended writing method
    QString password;//suggested writing method

1.6. Avoid using Hungarian nomenclature

Today's development tools are quite smart, and it is not necessary to know the type of a variable through its name.
1.7. Avoid using the same name for different purposes

It may be misinterpreted by the person reading the code.

2. Notes

2.1. Basic principles

The code should be as self-explanatory as possible, try to make the code itself easy to understand. That is, try not to write comments, unless it is a place that needs special instructions.
2.2. Do not write block comments

Block comment: A multi-line comment text that explains its function or identifies copyright information in front of a function or class. This kind of block comment has little positive meaning.
2.3. Situations where comments should be written

    When a piece of code has such a high level of inherent complexity that it cannot be easily understood by someone without in-depth expertise.
    When there is a deliberate departure from good design principles for some reason. For example, if you deliberately copied a piece of code, you can explain why you did it in the comments.

2.4, the principle of annotation

    Make sure that comments provide important information to the reader of the code that is often not obvious in the code itself.
    It should explain why the code does what it does, not how to do it. That is, it should explain why this code exists, but to understand how the code does it, you should look at the code itself rather than the comments.
    Comments should be as short and expressive as possible.
    Annotations also require maintenance.

3. Function

3.1. A function only does one thing

When the function code has the following signs, you should consider splitting the function:

    The number of lines of code for the function is very high.
    When giving a function an expressive name to describe what the function does, the conjunctions "and" and "or" cannot be avoided in the function name.
    When it is found that the function body is divided into several parts unconsciously.
    The function contains a large number of if-else and switch-case statements.
    The function has many incoming parameters, especially bool type parameters.

3.2. Make the function as small as possible

There may be many people who disagree here, but I agree with the author: the function should be as small as possible, ideally four or five lines, at most a dozen lines.

The overhead of function calls is not a problem, modern c++ compilers and their good optimizations and good CPUs can execute tens of billions of instructions per second. It is often bad architecture and design that really cause performance problems, and only in extreme special cases do you need to worry about the overhead of function calls.
3.3. Function parameters and return values

    Function parameters should be as few as possible. Preferably no parameters or 1 parameter, do everything possible to have no more than 3 parameters.
    Whenever possible, member functions should have no parameters except where necessary. Member functions are generally used to manipulate the internal state of the class. If the member function does not use member variables, it is better to check whether the function is placed outside the class as an independent function.
    Avoid flag parameters. The parameters of flag type are generally bool type, and the function performs different operations according to the flag passed in. This violates the principle that a function does one thing, and the function should be split at this time.
    Avoid using output parameters (non-pointer, non-reference) in order to make the function return multiple values. When you want a function to return multiple values: if the return values ​​are not closely related, you can use std::tuple or std::pair; and if the returned values ​​​​are highly cohesive, you can encapsulate these data into classes or structures deal with.
    Avoid returning nullptr when a function returns a variable of pointer type. Because after returning nullptr, you will have to add a processing path when the returned pointer is empty or add code for judging null operation in the code after calling the function. Solution: First, the function creates an object on the stack and returns it, and uses std::move semantics when receiving, which avoids expensive copy construction; second, creates an object on the stack before calling the function and then uses the non-reference of the object as a parameter passed to the function.

3.4. Make good use of const qualifiers

Violation of const will cause compilation errors, which can save debugging time, and the use of const can enable the compiler to support some optimizations, that is, improve program execution performance.

Correctly interpret the object modified by const: const always modifies the content on its left, and when there is no content on the left, it modifies the content on the right (the pointer to the object or the object itself).

4. Mandatory type conversion

    Avoid using casts whenever possible, and you should try to eliminate design problems that lead to using casts.
    Only C++-style casts should be used when unavoidable, because the compiler checks C++-style casts and not C-style casts.
    Try to use static_cast<>, const_cast<>, if not extremely necessary, do not use reinterpret_cast<>, dynamic_cast<>

Five, macro

Don't use macros, if you want to define a constant you should use const.
 

Guess you like

Origin blog.csdn.net/m0_64560763/article/details/131006981