Witam,
W C++ generalnie nie da się przesłonić metody wirtualnej (chyba, że w tym nowym standardzie, którego nie znam jeszcze), ale co sądzicie o zastosowaniu takiego triku w celu umożliwienia takiego przesłonienia?
class A {
public:
virtual void method();
}
class B : public A {
public:
void method(int = 0);
}
Wtedy method w klasie B nie implementuje metody wirtualnej z klasy A ponieważ mamy tu do czynienia z innym zestawem argumentów. Co więcej nie zachodzi żadna niejednoznaczność przy wywoływaniu metody z klasy B.
Możemy nawet metodę void method(int = 0) uczynić wirtualną i w ten sposób wszystkie klasy pochodne po B będą mogły sobie wybrać czy implementować metodę z klasy B czy z A.
Czy standard mówi coś na ten temat?
Przykład zastosowania. Mamy abstrakcyjny Kontener i dziedziczące po nim Set i List. Kontener ma metodę
ConstIterator insert(const T&)
, która zwraca iterator na nowo dodany element. Z uwagi, że pewne kontenery (jak Set) mogą udostępniać tylko ConstIterator (co by nie zmienić elementu i nie zaburzyć porządku w zbiorze) to nasz abstrakcyjny Container też musi zwracać ConstIterator.
Jednak nasza klasa List chciałaby udostępniać nam zwykły Iterator zezwalający na edycję wskazywanego elementu. Posiada wiec metodę przesłaniającą insert z klasy Kontener
Iterator insert(const T&, int = 0)
.
Co sądzicie o takim sztucznym przesłanianiu metod wirtualnych?
I drugie szybkie pytanie na zbliżony temat. Jak się mają argumenty domyślne do metod wirtualnych? Weźmy taki podobny do poprzedniego przykład:
class A {
public:
virtual void method(int);
}
class B : public A {
public:
void method(int = 0);
}
Czy możemy korzystając ze wskaźnika A* w wywołać metodę w taki sposób? Przypuszczam, że nie, ale są jakoś skonkretyzowane zasady tym rządzące?
A* a = new B;
a->method();
Albo odwrotnie:
class A {
public:
virtual void method(int = 0);
}
class B : public A {
public:
void method(int);
}
I znów:
A* a = new B;
a->method();