Non è consentito dallo standard, tuttavia è possibile utilizzare uno dei seguenti due metodi per ottenere un comportamento simile.
La prima sarebbe quella di utilizzare using
per modifica la visibilità del metodo a privati , impedendo così ad altri di utilizzarlo. Il problema con questa soluzione è che chiamare il metodo su un puntatore della super-classe non genera un errore di compilazione.
class B
{
public:
virtual void f();
};
class D : public B
{
private:
using B::f;
};
La soluzione migliore che ho trovato finora per ottenere un errore di compilazione quando si chiama il metodo D
s è quello di utilizzare un static_assert
con una struttura generica che eredita da false_type
. Fintanto che nessuno chiama mai il metodo, la struttura rimane non controllata e il static_assert
non fallirà.
Se il metodo è chiamato, tuttavia, la struttura è definita e il suo valore è falso, pertanto static_assert
ha esito negativo.
Se il metodo non viene chiamato, ma si tenta di chiamare su un puntatore della classe super, poi D
s metodo non è definito e si ottiene un errore di compilazione undefined reference
.
template <typename T>
struct fail : std::false_type
{
};
class B
{
public:
virtual void f()
{
}
};
class D : public B
{
public:
template<typename T = bool>
void
f()
{
static_assert (fail<T>::value, "Do not use!");
}
};
Un'altra soluzione potrebbe essere quella di un'eccezione quando il metodo è usato, ma sarebbe solo un tiro su runtime.
Com'è possibile? Vuoi l'errore del compilatore in 'D * d = new D(); static_cast (d) -> f() '? –
@BryanChen Se viene lanciato per puntare alla classe base, dovrebbe agire come un puntatore alla classe base, nel qual caso 'D :: f' verrebbe comunque chiamato, quindi sì. –
E quale comportamento ti aspetteresti allora? – Theolodis