C ++ core principles C.30: If you need to clear a class action destruction, defined destructor

C.30: Define a destructor if a class needs an explicit action at object destruction

If a class needs to clear the destruction operation, defined destructor

 

Reason (reason)

A destructor is implicitly invoked at the end of an object's lifetime. If the default destructor is sufficient, use it. Only define a non-default destructor if a class needs to execute code that is not already part of its members' destructors.

Destructors are invoked implicitly at the end of life of the object. If the default destructor is sufficient, it is not necessary otherwise defined. Only required operation member outside its destructor process defined in a non-default class destructor.

 

Example (Example)

template<typename A>
struct final_action {   // slightly simplified
    A act;
    final_action(A a) :act{a} {}
    ~final_action() { act(); }
};

template<typename A>
final_action<A> finally(A act)   // deduce action type
{
    return final_action<A>{act};
}

void test()
{
    auto act = finally([]{ cout << "Exit test\n"; });  // establish exit action
    // ...
    if (something) return;   // act done here
    // ...
} // act done here

The whole purpose of final_action is to get a piece of code (usually a lambda) executed upon destruction.

final_action sole purpose is to make a piece of code (usually a lambda expression) execution is destroyed in final_action.

 

Note (Note)

There are two general categories of classes that need a user-defined destructor:

There are generally two cases need a user-defined class destructor.

  • A class with a resource that is not already represented as a class with a destructor, e.g., a vector or a transaction class.

    Class management resource contains no performance class destructor. Such as vector or transaction class.

  • A class that exists primarily to execute an action upon destruction, such as a tracer or final_action.

    The main object of the present type is to perform an action on destruction. For example tracer and final_action.

 

Example, bad (negative sample)

class Foo {   // bad; use the default destructor
public:
    // ...
    ~Foo() { s = ""; i = 0; vi.clear(); }  // clean up
private:
    string s;
    int i;
    vector<int> vi;
};

The default destructor does it better, more efficiently, and can't get it wrong.

The default destructor can do better and more efficiently, there will not be wrong.


Note (Note)

If the default destructor is needed, but its generation has been suppressed (e.g., by defining a move constructor), use =default.

If desired default destructor, but which have been suppressed is generated (e.g., because the movement is defined constructor), use = default (explicit request generation, translator's note).

 

Enforcement (Suggestions)

Look for likely "implicit resources", such as pointers and references. Look for classes with destructors even though all their data members have destructors.

Looking for possible "implicit resource", such as pointers and references. Looking class destructor, even if all the data members have their destructors.

 

Original link:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c30-define-a-destructor-if-a-class-needs-an-explicit-action-at-object-destruction

 


 

I think this article helpful? Welcome thumbs up and share it with more people.

Read more updated articles, please pay attention to micro-channel public number of object-oriented thinking []

Published 408 original articles · won praise 653 · views 290 000 +

Guess you like

Origin blog.csdn.net/craftsman1970/article/details/104299878