Mam klasy Base
wyznaczającą explicit operator bool
:wirtualnej wyraźny operator konwersji nadrzędnymi
struct Base {
virtual explicit operator bool() const {
return true;
}
};
I mam podklasy Derived
, określającym operator bool
:
struct Derived : Base {
operator bool() const override {
return false;
}
};
Jak można zaobserwować, Derived::operator bool
jest wyraźnie nie oznaczone explicit
, ale oznaczone override
, więc spodziewałem się kompilator do złożenia skargi. Jednak zarówno gcc, jak i clang wydają się zgadzać, że jest to poprawne. Czy moje oczekiwania były nieuzasadnione?
Ponadto, jeśli mogę użyć klas w następujący TakesBool(base)
nie skompilować (zgodnie z oczekiwaniami), ale TakesBool(derived)
robi:
void TakesBool(bool b) {}
int main() {
//Base base; TakesBool(base); // compilation error (as expected)
Derived derived; TakesBool(derived);
return 0;
}
Wydaje się to wskazywać, że Derived
ma (nie explicit
) operator bool
, który jest jednak oznaczony jako override
bez deklaracji virtual
. Jak to jest możliwe?
Jeśli chodzi o brak potrzeby "wirtualnego" w klasie pochodnej, jeśli klasa podstawowa została oznaczona jako "wirtualna", jest domyślnie dorozumiana również dla wszystkich klas pochodnych. Słowo kluczowe "override" jest bardziej wskazówką dla kompilatora, więc nie próbujesz przesłonić funkcji za pomocą innego podpisu (np. Deklarując funkcję w klasie pochodnej, która przyjmuje inne argumenty niż funkcja w klasie bazowej). Zatem te słowa kluczowe są nieistotne dla pytania. –
Wirtualna wysyłka nadal ma miejsce. 'Base * pbase = & deriv; TakesBool ((bool) * pbase); 'wywoła' Derived :: operator bool'. Domyślam się, że 'explicit' nie jest częścią sygnatury funkcji, więc możesz pominąć konwersję' explicit' z tekstem innym niż'exitive '. Nie jestem pewien, czy to zachowanie jest poprawne. –
To jest jak posiadanie funkcji 'protected: virtual' w klasie bazowej z' public: override' w klasie pochodnej. Nie stanowi to żadnego problemu. –