Así que tengo una clase base abstracta sin métodos abstractos. Con el fin de hacer cumplir la abstracción, he declarado el destructor (no trivial) como virtual pura:Herencia virtual pura, herencia múltiple, y C4505
class AbstractClass
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
Esto construye y funciona como se esperaba; la salida de un bloque de código que simplemente define una instancia de ConcreteClass es
AbstractClass::AbstractClass() ConcreteClass::ConcreteClass() ConcreteClass::~ConcreteClass() AbstractClass::~AbstractClass()
Ahora, cuando tengo derivar AbstractClass de otra clase se utiliza como una clase de interfaz, sí que tiene un (trivial) destructor virtual (puro o de otra manera) , aún funciona:
class IAlpha
{
public:
virtual ~IAlpha() = 0 {}
};
class AbstractClass : public IAlpha
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
El problema surge cuando intento de implementar dos interfaces diferentes de esta manera:
class IAlpha
{
public:
virtual ~IAlpha() = 0 {}
};
class IBeta
{
public:
virtual ~IBeta() = 0 {}
};
class AbstractClass : public IAlpha, public IBeta
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
en este punto, cuando bu ilding, recibo el siguiente mensaje de advertencia:
warning C4505: 'AbstractClass::~AbstractClass' : unreferenced local function has been removed
Curiosamente, sin embargo, la salida sigue mostrando AbstractClass::~AbstractClass()
recibiendo llamadas.
¿Esto es un error en MSVC9 (VS 2008)? ¿Puedo ignorar esta advertencia?
Editar: He intentado separar las definiciones de métodos virtuales puros de la definición de clase también, ya que aparentemente la sintaxis = 0 {}
no es realmente válida. Desafortunadamente, C4505 todavía aparece, si especifico inline
o no.
Como no he encontrado ninguna forma de #pragma
de advertir estos métodos (la advertencia se dispara desde otras partes del código), es posible que tenga que eliminar el especificador virtual puro de AbstractClass
y confiar en que los constructores protegido. No es una solución ideal, pero es mejor que reescribir la jerarquía de clases para evitar una advertencia errónea.
He intentado el código en su enlace; recibe la misma advertencia aunque, como antes, funciona correctamente cuando se ejecuta. – somethingdotjunk