Get yourself used to C++ (Part 1) (Article 1 ~ Article 4)

Article 1: Treat C++ as a language federation

The four sub-language parts of C++: C, Object-oriented c++, template c++, STL

please remember:

C++ efficient programming rules vary depending on the situation, depending on which part of C++ you use.

 

Article 2: Try to replace #define with const, enum, inline

Practice code

// 含有数组元素的类
class ArrData {
public:
    ArrData() = default;

    ArrData(int ip, int jp) : i(ip), j(jp), arr{1, 2, 3}, vec(3, 0) {}

private:
    int i;
    int j;
    int arr[5];
    vector<int> vec;
//    static int snum = 0; // 错误,必须在类外定义,类里面声明
    static int snum; // 仅声明,right
    static const int scnum = 0; // right,仅有const整型static成员可以在类里面定义
    const int cnum = 0; // right
    int num = 0; // right
//    static double sfactor = 0.0; // 错误,非整形的static成员均不能再类里面定义
    static double sfactor; // 仅声明,right
//    static const double scfactor = 0.0; // 错误,非整形的static成员均不能再类里面定义
    static const double scfactor; // 仅声明,right
    const double cfactor = 0.0; // right
    double factor = 0.0; // right
};

int ArrData::snum = 0;
double ArrData::sfactor = 0.0;
const double ArrData::scfactor = 0.0;

please remember:

For simple constants, it is best to replace #define with const objects or enums

For macros that resemble functions, it is best to replace #define with inline functions

 

Item 3: Use const whenever possible

Understand the meaning of several const forms

        const Widget * pw; // pw指向内容不可修改
        Widget const * pw; // pw指向内容不可修改
        Widget * const pw; // pw指针不可修改,即不能指向其他内容
        const Widget * const pw; // pw指向内容不可修改,且pw指针不可修改,即不能指向其他内容
        
        vector<int> vec{1,2,3,4};
        const auto iter = vec.begin(); // const iter, iter不可修改
        ++iter; // 错误,iter迭代器不可修改,类似于指针不可修改
        auto citer = vec.cbegin(); // citer迭代器指向内容不可修改

const object can only call const member functions;

Non-const objects can call any member function;

const member function can access any member variable as long as it is not modified (in fact, it can also be modified, as detailed below);

Some of the container interfaces in the standard library (such as empty(), size(), and some that will modify the content of the container, such as operator[], at(), etc.) provide const and non-const versions of the interface , This is an important feature of C++, if two functions are only constant, they can be overloaded ;

bitwise const: Member functions can only be said to be const when they do not modify any member variables

Logical const:  const member function can modify some bits, but it can be implemented with mutable only if the client cannot detect it.

Variable data members, mutable, so that const member functions can also access and modify its value;

Avoid duplication in const and non-const member functions:

1) You can make the non-const version call the const version, pay attention to the type conversion in the call;

2) The const version should not be called to call the non-const version, which breaks the rule that const does not change members;

    // const版本[]
    const char& operator[](size_t position) const {
        ....
        return data[position];
    }
    // non-const版本[]
    char& operator[](size_t position) {
        ....
        // 注意,先转换为const object调用const版本,否则将陷入non-const的无穷无尽递归调用中
        // 再调用const_cast去掉返回引用的const属性
        return const_cast<char&>(static_cast<const Widget &>(*this)[position]); 
    }

please remember:

Declaring something as const can help the compiler detect incorrect usage. const can be used for objects in any scope, function parameters, function return types, member functions, etc.;

The compiler enforces bitwise const detection, but your code should implement logical const according to the business;

When the const and non-const member functions have substantially equivalent implementations, make the non-const version call the const version to avoid code duplication;

 

Item 4: Make sure that the object is initialized before being used

The array in C does not guarantee that its content is initialized, but the vector container in C++ has this guarantee. The object calls the default constructor, and the built-in type is initialized by value;

        vector<int> vec(5);  // 默认值初始化为0
        vector<double> vec2(4); // 默认值初始化为0.0

The initial value of the member variable is read in from a file or database and other similar scenarios. An Init function should be extracted to complete this function for all constructors to call. It should not be initialized in the initial value column .

A static object has a life span from being constructed until the end of the program . The objects in the function are called local static objects, and the rest are called non-local static objects , including:

1) Global object;

2) Objects defined in the namespace scope;

3) Objects declared as static in the class, function, and file scope;

C++ does not clearly define the relative order of initialization of non-local static objects scheduled in different compilation units. Because this is quite difficult or even impossible to complete.

please remember:

Manual initialization for built-in type objects, because C++ does not guarantee to initialize them;

It is better to use the initial value column of the members in the constructor, instead of using assignment operations in the body of the constructor. The arrangement order of the member variables listed in the initial value column should be the same as the order of their declaration in the class (this is not necessarily true. It doesn't matter if it is different, but it is necessary to ensure that the initial value column uses parameters, and do not let the initialization of the member use another member, there is a historical relationship);

To avoid the problem of "initialization order across compilation units", please replace non-local static objects with local static objects

 

 

Guess you like

Origin blog.csdn.net/u010323563/article/details/112427122