Quindi ho una classe base astratta senza metodi astratti. Per far valere astrattezza, ho dichiarato il (non banale) distruttore come pura virtuale:Eredità virtuale pura, ereditarietà multipla e 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;
}
};
Questo costruisce e funziona come previsto; l'uscita di un blocco di codice che definisce semplicemente un'istanza di ConcreteClass è
AbstractClass::AbstractClass() ConcreteClass::ConcreteClass() ConcreteClass::~ConcreteClass() AbstractClass::~AbstractClass()
Ora, quando ho derivare AbstractClass da un'altra classe utilizzata come classe di interfaccia, si avente una (banale) distruttore virtuale (puro o altrimenti) , funziona ancora:
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;
}
};
Il problema sorge quando si tenta di implementare due interfacce differenti in questo modo:
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;
}
};
a questo punto, quando BU ilding, ricevo il seguente avviso:
warning C4505: 'AbstractClass::~AbstractClass' : unreferenced local function has been removed
Stranamente, però, l'output mostra ancora AbstractClass::~AbstractClass()
sempre chiamato.
Si tratta di un bug in MSVC9 (VS 2008)? Posso tranquillamente ignorare questo avviso?
Modifica: ho provato a separare le definizioni del metodo virtuale puro anche dalla definizione della classe, in quanto apparentemente la sintassi = 0 {}
non è effettivamente valida. Sfortunatamente, C4505 si presenta ancora, sia che io specifichi inline
oppure no.
Poiché non ho trovato alcun modo di inviare questo avviso solo per questi metodi (l'avviso viene attivato da altre parti del codice), potrei dover rimuovere lo specificatore virtuale puro da AbstractClass
e fare affidamento sui costruttori protetta. Non è una soluzione ideale, ma batte rearchitecting la gerarchia di classe per aggirare un avviso errato.
Ho provato il codice nel tuo collegamento; riceve lo stesso avvertimento anche se, come prima, funziona correttamente durante l'esecuzione. – somethingdotjunk