Code Smell 205 - Code in Destructors

Maxi Contieri - Apr 9 '23 - - Dev Community

You deallocate things in your destructors

TL;DR: Don't use destructors. And don't write functional code there.

Problems

  • Coupling

  • Unexpected results

  • Memory leaks

Solutions

  1. Don't use destructors.

  2. Follow the Rule of Zero

  3. Let the Garbage Collector work for you

Context

A class destructor is a special method that is called when an object is destroyed or goes out of scope.

In the past, we had no garbage collectors and destructors were responsible for cleaning up any resources that the object has acquired during its lifetime, such as closing open files or releasing memory allocated on the heap.

Nowadays, object destruction is automatic in most modern programming languages.

Sample Code

Wrong

class File {
public:
    File(const std::string& filename) {
        file_ = fopen(filename.c_str(), "r");
    }

    ~File() {
        if (file_) {
            fclose(file_);
        }
    }

private:
    FILE* file_;
};

Enter fullscreen mode Exit fullscreen mode

Right

class File {
public:
    File() : file_(nullptr) {}

    bool Open(const std::string& filename) {
        if (file_) {
            fclose(file_);
        }
        file_ = fopen(filename.c_str(), "r");
        return (file_ != nullptr);
    }

    bool IsOpen() const {
        return (file_ != nullptr);
    }

    void Close() {
        if (file_) {
            fclose(file_);
            file_ = nullptr;
        }
    }

    ~File() {
        // Instead of closing the file we throw an exception 
        // If it is open (which is an invalid scenario)
        if (file_) {
            throw std::logic_error("File is still open in destructor");
        }
    }

private:
    FILE* file_;
};

Enter fullscreen mode Exit fullscreen mode

Detection

[X] Automatic

Linters can warn us when we write code in destructors

Exceptions

In very critical low-level code we cannot afford a garbage collector.

Exceptions are very few.

In other cases writing code in destructors is a symptom of premature optimization.

Tags

  • Premature Optimization

Conclusion

Writting code in destructors is a sign of sloppiness and laziness.

We need to understand the life cycle of our objects and manage the events accurately.

Relations

https://maximilianocontieri.com/code-smell-142-queries-in-constructors

Disclaimer

Code Smells are just my opinion.

Credits

Photo by Crawford Jolly on Unsplash


The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We cause accidents.

Nathaniel S. Borenstein

https://maximilianocontieri.com/software-engineering-great-quotes


This article is part of the CodeSmell Series.

https://maximilianocontieri.com/how-to-find-the-stinky-parts-of-your-code

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .