Some considerations for construction and destruction

  1. Variables need to be initialized. Try to use the initialization list for initialization. If it is not initialized, the value of the variable is randomly uncertain.
class Point {
    
    
    int x;
    int y;
};
// 改进之后后
class Point {
    
    
   public:
    Point(int x, int y) : _x(x), _y(y) {
    
    }

   private:
    int _x;
    int _y;
};
  1. Private destructor, the class object cannot allocate space on the stack. It can only be allocated on the heap , but cannot be directly released by delete.
#include <iostream>
using namespace std;

class Point {
    
    
   public:
    Point(int x, int y) : _x(x), _y(y) {
    
    }
    void destory() {
    
     delete this; }
   private:
    ~Point() {
    
    }

   private:
    int _x;
    int _y;
};

int main(int argc, char const *argv[]) {
    
    
    //Point p(1, 2);// error
    Point *p1 = new Point(1, 2);
    //delete p1;//error
    p1.destory();
    return 0;
}
  1. Block new and delete, objects can only be allocated on the stack
#include <iostream>
using namespace std;

class Point {
    
    
   public:
    ~Point() {
    
    }
    Point(int x, int y) : _x(x), _y(y) {
    
    }
    // 删除或者私有new 和 delete
    void* operator new(size_t size) = delete;
    void operator delete(void* ptr) = delete;
    //    private:
    //     void* operator new(size_t size);
    //     void operator delete(void* ptr);

   private:
    int _x;
    int _y;
};

int main(int argc, char const* argv[]) {
    
    
    Point* p1 = new Point(1, 2);//error
    delete p1;
    return 0;
}
  1. The polymorphic base class is declared as a virtual destructor, otherwise it may cause a memory leak. The code is as follows.
    On the contrary, do not set a virtual destructor, which will result in redundant memory.
#include <iostream>
using namespace std;

class Base {
    
    
   public:
    Base() {
    
     a = new char[100]; }
    ~Base() {
    
    
        cout << __func__ << endl;
        delete[] a;
    }

   private:
    char* a;
};
class Derived : public Base {
    
    
   public:
    Derived() {
    
     b = new char[100]; }
    ~Derived() {
    
    
        cout << __func__ << endl;
        delete[] b;
    }

   private:
    char* b;
};

int main(int argc, char const* argv[]) {
    
    
    Base* d = new Derived();
    delete d;
    return 0;
}

Output:

[root@localhost poco_demo]# g++ tt.cpp -std=c++11 -o tt
[root@localhost poco_demo]# ./tt
~Base
  1. Don't throw exceptions in the destructor. This may cause errors such as memory failure. The correct approach is to catch and deal with these errors, let the destruction end normally, instead of throwing out layer by layer.

  2. Don't destruct and construct functions anymore, use virtual functions. The virtual function is controlled through the virtual function table, and the class accesses the virtual function table through the pointer of the virtual function table. The virtual function table pointer is used as a member variable, initialized during construction, and ends its life cycle during destruction. In the inheritance system, this would be more confusing.

  3. Don't private a virtual function, because it doesn't make much sense. As long as you get the _vptr, you can access the virtual function table, and then bypass the private access to the virtual function.

Guess you like

Origin blog.csdn.net/niu91/article/details/109938875