Search code examples
c++destructorvirtual-destructor

deleted function 'virtual Classname::~Classname()' overriding non-deleted function VIRTUAL DESTRUCTOR


I am trying to find the problem in this code, it does not compile in C++14.

The original problem was to make this compile 'without editing Object or modifying drawObject()'s prototype':

#include <iostream>

class Object {
    virtual ~Object() {}
};

class Line : public Object {
public:
    virtual void draw() {std::cout << "draw" << std::endl;}
    ...
};

void drawObject(Object * obj) {
    obj->draw();
}

int main() {
    Line line;
    drawObject(&line);
}

So I casted obj to be a Line, then had another issue with the destructor of Object, since it is private.

I think I need to define the destructor of the Line class, but failing to do so.

Also, I am not permitted to edit Object class (obviously...) nor the prototype of drawObject().

#include <iostream>

class Object {
    virtual ~Object() {}
};

class Line : public Object {
public:
    virtual void draw() {std::cout << "draw" << std::endl;}
};

void drawObject(Object *obj) {
    ((Line*)obj)->draw();
}

int main() {
    Line line ;
    drawObject(&line);
}

The error i'm getting:

     error: deleted function 'virtual Line::~Line()' overriding non-deleted function

Solution

  • A private destructor means a class cannot be a base class. A base class destructor is implicitly used by both constructors (in case initialization throws exceptions) and destructor of a deriving class.

    So there is absolutely no way for you to derive Line from Object. Best you can do is make Line unrelated to Object

    class Line {
    // ...
    };
    

    And perform a cast at the call site as well

    drawObject((Object*)&line);
    

    But that's an example of really bad C++. While a reinterpret cast (what this C-style cast amounts to) between unrelated pointers to classes is generally legal (the pointers should have the same size and representation, and barring any extended alignment specification), and while you can convert back, this entirely ignores the type system and throws all caution to the wind.

    Do not replicate outside of pub-quizzes and silly riddles.