C ++ - virtual destructors and linker errors

I got this interface, which I wrote:

#ifndef _I_LOG_H #define _I_LOG_H class ILog { public: ILog(); virtual ~ILog(); virtual void LogInfo(const char* msg, ...) = 0; virtual void LogDebug(const char* msg, ...) = 0; virtual void LogWarn(const char* msg, ...) = 0; virtual void LogError(const char* msg, ...) = 0; private: Monkey* monkey; }; #endif 

Methods are purely virtual and therefore must be implemented by getting classes. If I try to create a class that inherits this interface, I get the following linker errors:

 Undefined reference to ILog::ILog Undefined reference to ILog::~ILog 

I understand why a virtual destructor exists (to make sure the derived destructor is called), but I do not understand why I get this linker error.

EDIT: Okay, so I need to define a virtual destructor as well. But can I still run the material in the definition of a virtual destructor, or will it just call the destructor of the derived classes and skip it? For example, this trigger:

 virtual ~ILog() { delete monkey; } 
+4
source share
3 answers

You did not define a constructor and destructor, you only declared them

Try

 class ILog { public: //note, I want the compiler-generated default constructor, so I don't write one virtual ~ILog(){} //empty body virtual void LogInfo(const char* msg, ...) = 0; virtual void LogDebug(const char* msg, ...) = 0; virtual void LogWarn(const char* msg, ...) = 0; virtual void LogError(const char* msg, ...) = 0; }; 
  • Constructor: after declaring a constructor, any constructor, the compiler does not create a default constructor for you. The constructor of the derived class tries to call the constructor of the interface, and it is not defined, it is simply declared. Either specify a definition or delete the declaration
  • Destructor: other considerations left alone (e.g. similar considerations as above), your destructor is virtual. Every unclean virtual function must have a definition (because it is by definition used).

Can I still do things in the virtual destructor definition, or will it just call my derived class destructor and skip it? For example, will this trigger

Yes, you can. When a destructor of a derived class is called, it automatically calls the destructor of the base class. However, I can’t think of what it would be wise to do an interface destructor. But technically you can do something in the destructor, even if it's virtual

+10
source

You forgot to add an empty function for the virtual destructor. The body of the function actually does nothing, and C ++ can put the low-level destruction code in the destructor of the derived class (not quite sure about this), but it still requires:

 #ifndef _I_LOG_H #define _I_LOG_H struct ILog { virtual ~ILog(); // virtual ~ILog() = 0; // either works virtual void LogInfo(const char* msg, ...) = 0; virtual void LogDebug(const char* msg, ...) = 0; virtual void LogWarn(const char* msg, ...) = 0; virtual void LogError(const char* msg, ...) = 0; }; #endif 

CPP file:

 ILog::~ILog() { // this does get called } 

Updated example:

 #include <iostream> struct Monkey { int data; }; struct ILog { ILog() : monkey(0) {} virtual ~ILog() = 0; virtual void LogInfo(const char* msg, ...) = 0; virtual void LogDebug(const char* msg, ...) = 0; virtual void LogWarn(const char* msg, ...) = 0; virtual void LogError(const char* msg, ...) = 0; void storeMonkey(Monkey* pM) { delete monkey; monkey = pM; } void message() { std::cout << "monkey->data contains " << monkey->data; } private: Monkey* monkey; }; struct ILogD : ILog { int data; ILogD(Monkey* pM) { storeMonkey(pM); } void LogInfo(const char* msg, ...) {}; void LogDebug(const char* msg, ...) {}; void LogWarn(const char* msg, ...) {}; void LogError(const char* msg, ...) {}; }; ILog::~ILog() { delete monkey; } int main() { ILogD o(new Monkey()); o.message(); } 
+3
source

Just enter the built-in version of the constructor and destructor, and the compiler will not create a link to them for the linker to fail.

 ILog() {}; virtual ~ILog() {}; 
0
source

Source: https://habr.com/ru/post/1387638/


All Articles