Search code examples
visual-c++mfcdestructorcode-analysis

Why is VS flagging C26432 for my destructor?


In my header file I have:

CPTSDatabase();
virtual ~CPTSDatabase();
void    CloseDatabase();

In my source file I have:

CPTSDatabase::~CPTSDatabase()
{
    CloseDatabase();
}

void CPTSDatabase::CloseDatabase()
{
    if (m_dbDatabase.IsOpen())
        m_dbDatabase.Close();
}

Code analysis is saying:

C26432: If you define or delete any default operation in the type class CPTSDatabase, define or delete them all (c.21).

I have read up on this but can't see the issue. I have a constructor and destructor and I never use the word delete`. What have I missed?


Solution

  • First, remember that some of those /analyze warnings including C26432 are informational and optional. If you don't want that particular C++ Core Guidelines check enabled, you can disable it. See Microsoft Docs

    All it's really telling you is "Hey, have you thought about how you want to handle copy or move for your class?"

    The general recommendations are that if you define a dtor, then you should address the copy constructor, move constructor, copy assignment operator, and move assignment operator. For example, it seems logical that your class can support move operations, but not copy operations since it owns a system resource (some sort of database handle), so you should probably make it:

    CPTSDatabase();
    
    // Default move ctor and move operator
    CPTSDatabase(CPTSDatabase&&) = default;
    CPTSDatabase& operator= (CPTSDatabase&&) = default;
    
    // Delete the copy ctor and copy operator
    CPTSDatabase(CPTSDatabase const&) = delete;
    CPTSDatabase& operator=(CPTSDatabase const&) = delete;
    
    // If using virtual for a class that's not just an interface,
    // it's recommended to use a virtual dtor.
    virtual ~CPTSDatabase();
    

    That said, if your class itself contains variables that do not support move (like std::mutex or std::atomic), then you should delete those as well.

    CPTSDatabase();
    
    CPTSDatabase(CPTSDatabase&&) = delete;
    CPTSDatabase& operator= (CPTSDatabase&&) = delete;
    
    CPTSDatabase(CPTSDatabase const&) = delete;
    CPTSDatabase& operator=(CPTSDatabase const&) = delete;
    
    virtual ~CPTSDatabase();
    

    Keep in mind that deleting these basic operations makes your class more restricted in how you can use it, but it's better than your class being used in ways that break it.