Básicamente no entiendo los clang's -Wweak-vtables
. Esto es lo que observé hasta ahora:
Caso uno: (activa la advertencia)
class A {
public:
virtual ~A(){}
};
class B : public A {
public:
virtual ~B(){}
};
int main(){}
Caso dos: (no activa la advertencia)
class A {
public:
virtual ~A(){}
};
int main(){}
Caso tres: (no activa la advertencia)
class A {
public:
virtual ~A();
};
A::~A(){}
class B : public A {
public:
virtual ~B(){}
};
int main(){}
Caso cuatro: (Activa la advertencia)
class A {
public:
virtual ~A(){}
virtual void fun(){}
};
class B : public A {
public:
virtual ~B(){}
};
int main(){}
Caso cinco: (no activa la advertencia)
class A {
public:
virtual ~A(){}
virtual void fun();
};
class B : public A {
public:
virtual ~B(){}
};
int main(){}
Caso seis: (no activa la advertencia)
class A {
public:
virtual ~A(){}
virtual void fun(){}
};
class B : public A {};
int main(){}
Caso siete: (no activa la advertencia)
class A {
public:
virtual ~A(){}
virtual void fun(){}
};
class B : public A {
public:
virtual void fun(){}
};
int main(){}
La advertencia exacta es
warning: 'A' has no out-of-line virtual method definitions; its vtable
will be emitted in every translation unit [-Wweak-vtables]
Entonces, aparentemente, si no declaro una función virtual no en línea en una clase, causa algún tipo de problema si y solo si derivo de ella y la clase derivada tiene un destructor virtual.
Preguntas:
- ¿Por qué es esto un problema?
- ¿Por qué se soluciona esto declarando una función virtual? (Advertencia habla de definiciones)
- ¿Por qué no se produce la advertencia cuando no procedo de la clase?
- ¿Por qué no aparece la advertencia cuando la clase derivada no tiene un destructor virtual?
B
debe ser virtual (ya que se ha declarado el destructor de la clase basevirtual
).~B()
, por lo tanto, el compilador no crea una instancia implícita de la definición predeterminada. ¿Cómo puede ser virtual si no existe? La trivialidad de los ejemplos está provocando algunos efectos contrarios a la intuición.