"C++ Advanced Programming" Reading Notes (3: Coding Style)

1. References

2. It is recommended to read the book "21 Days to Learn C++" to get started. The link of the notes is as follows

1. Document your code

  • In a programming context, documentation usually refers to comments in source files

1.1 Reasons for using annotations

1.1.1 Notes explaining the purpose
  • One of the reasons for using annotations is to illustrate how the client interacts with the code. In general, developers should be able to infer what a function does from the function name, the type of the return value, and the types and names of the parameters . However, the code itself cannot explain everything. Sometimes a function requires some preconditions or postconditions , and these need to be explained in comments. Exceptions that a function may throw should also be explained in comments
  • Example: In C++, it is impossible to explain that the saveRecord() method of the database object can only be called after the openDatabase() method, otherwise an exception will be thrown
    /*
        Throws:
        DatabaseNotOpenedException if the openDatabase() method has not been called yet.
    */
    RecordID saveRecord(Records record); // RecordID 只是 int 的别名,但用途一目了然
    

Note : When writing comments, those information that can be seen clearly through the return value type of the function name and the type and name of the formal parameters do not need to be added to the comments

1.1.2 Comments to illustrate complex code
  • For more complex code in specialized domains, it is good practice to use comments to describe the algorithms used and to state (for loops) invariants. An invariant is a condition that must be true during the execution of a piece of code , such as the iteration condition of a loop

insert image description here

1.1.3 Annotations for passing meta information
  • Another reason to use comments is to provide information at a level above the code . Meta information provides details about creating code, but not specific behavior of the code. For example, an organization might want to use meta information to track the original author of each method. You can also reference external documentation or other code using meta information
  • The following example gives several examples of meta information, including the author of the file, creation date, and provided features. Also included are inline comments representing metadata, such as a bug number corresponding to a line of code, to alert you to a possible problem in the code when you revisit it later

insert image description here

1.2 Comment style

1.2.1 Add comments to each line
  • One of the ways to avoid lack of documentation is to include a comment on each line. Commenting each line ensures that everything written has a specific reason. But in reality, if there are a lot of codes, too many comments will be very confusing and complicated, and it is impossible to do
  • It's usually not necessary to comment every line of code, but when the code is so complex that it needs to be, don't just translate the code into English, but explain what the code is actually doing
    if (result % 2 == 0){
          
          } // 错误:如果 result 对 2 求模结果为 0 
    if (result % 2 == 0){
          
          } // 正确:如果 result 为偶数 
    
1.2.2 Pre-comment
  • The team may decide that all source files begin with a standard comment, a place where program and file-specific important information can be documented. The descriptive information added at the top of each file is
    • last modified date
    • original author
    • The modification log file mentioned above
    • The feature ID given by
    • Copyright Information
    • A brief description of the file or class
    • unfinished features
    • known bugs
1.2.3 Fixed format comments
  • Writing comments in a standard format that can be parsed by external documentation generators is an increasingly popular programming approach. For C++, the free tool Doxygen (www.doxygen.org) parses comments and automatically generates HTML documentation, class diagrams, UNIX man pages, and other useful documentation
1.2.4 Special Notes
  • Before adding comments, first consider whether you can revise your code to avoid using them. For example, renaming variables, functions, and classes, rearranging the order of code steps, introducing well-named intermediate variables, etc.
  • If dealing with a less obvious API, include a reference to the API documentation where the API is explained
  • Remember to update the comments when you update the code. If the documentation of the code is full of error messages, it will be very confusing
  • If using annotations to divide a function into multiple sections, consider whether the function can be broken down into multiple smaller functions

2. Break down

  • Decomposition refers to dividing the code into small pieces. Ideally, each function or method should only complete one task
  • Any subtasks that are very complex should be decomposed into separate functions or methods

2.1 Decomposition by refactoring

  • Refactoring refers to rebuilding the structure of the code, and some techniques that can be used to refactor the code are given below
    • Enhanced Abstraction Techniques
      • Encapsulate fields: make fields private, access them using getter and setter methods
      • Make Types Generic: Create more generic types to better share code
    • Techniques for splitting code to make it more reasonable
      • Extract method: convert part of a large method into a new method that is easy to understand
      • Extract class: transfer part of the code of an existing class into a new class
    • Tips for Enhancing Code Names and Locations
      • Move method or field: move to a more appropriate class or source file
      • Rename a method or field: Change to a name that better reflects what it does
      • pullup: In OOP, pullup into the base class
      • push down: In OOP, move down to a derived class

2.2 Decomposition by Design

  • If you use module decomposition, you can put part of the code written later in modules, methods or functions. The program is usually not as dense as the code that puts all functions together, and the structure is more reasonable
  • Of course, it is still recommended to design the program before writing the code

3. Naming

  • The compiler has several naming conventions
    • Names cannot start with a number (e.g. 9to5)
    • Names containing two underscores (such as my__name) are reserved and should not be used
    • Names beginning with an underscore (such as _Name) are reserved and should not be used

3.1 Choose an appropriate name

insert image description here

3.2 Naming Conventions

  • 1. Counter

    • Programmers are accustomed to using i and j as counters and inner loop counters respectively, however beware of getting confused when nesting loops
    • When working with two-dimensional data, it is easier to use row and column as indexes than using i and j
  • 2. Prefix
    insert image description here

  • 3. Hungarian notation

    • Hungarian notation is a naming convention about variables and data members, the basic idea is to use a more detailed prefix instead of a letter (such as m) to indicate additional information
  • 4. Getters and Setters

    • If the class contains a data member such as mStatus, it is customary to access this member through the getter getStatus() and the setter setStatus()
    • To access boolean data members, is (not get) is usually prefixed, eg isRunning()
  • 5. Capitalize

    • Variables and data members almost always start with a lowercase letter and separate words with underscores (my_queue) or uppercase letters (myQueue)
    • Functions and methods are usually capitalized, but this book uses lowercase for functions and methods to distinguish them from class names
    • Capital letters can be used to indicate word boundaries for class and data member names

4. Use stylized language features

4.1 Using constants

  • The C++ language provides constants, which can assign a symbolic name to an unchanging value (for example, 2.71828)
    const double kApproximationForE = 2.71828182845904523536;
    

4.2 Using references instead of pointers

  • There are many benefits to replacing pointers with references
    • 1. First of all, references are safer than pointers , because references do not directly deal with memory addresses, nor are they nullptr
    • 2. Secondly, references are better than pointers in style , because references use the same syntax as stack variables, without symbols such as * and &
    • 3. Another advantage of using references is that it clarifies the ownership of memory
      • If one programmer writes a method and another programmer passes it a reference to an object, the object can obviously be read and modified, but the object's memory cannot be easily freed. It's not so obvious if you're passing a pointer

    Passing by pointer does not necessarily mean that the object will change, since the parameter may be a const T*. Whether passing a pointer or a reference modifies the object depends on whether the function prototype uses const T*, T*, const T&, or T&

5. Format

5.1 The brace alignment debate

  • In this book, except for function, class, and method names, curly braces are placed on the same line as the opening statement
void someFunction 
{
    
    
    if (condition) {
    
    
        cout << "condition was true" << endl;
    } else {
    
    
        cout << "condition was false" << endl;
    }
}

5.2 Arguments about spaces and parentheses

  • This book uses spaces after any keyword, before and after operators, after each comma in an argument list or function call, and parentheses to indicate the order of operations
if (i == 2) {
    
    
    j = i + (k / m);
}

Guess you like

Origin blog.csdn.net/qq_42994487/article/details/131076807