Implementacja funkcji wirtualnej z innym typem zwracanym

0

Witam.

Mam następujący problem. Weźmy sobie takie klasy:
class A
class B : public A
class C : public B
Oraz zastosujmy do nich wzorzec prototyp.

Teraz wiadomo, że jeśli dysponuję wskaźnikiem na A to mogę sobie klonować dokładnie to na co ten wskaźnik wskazuje, niezależnie czy jest to w rzeczywistości typu A, B czy C. Ale załóżmy, że czasem też dysponuję wskaźnikami na B i wtedy chciałbym by metoda clone zwracała mi wskaźnik na B, a nie na A korzystając z sygnatury dziedziczonej po A metody wirtualnej.

Pytanie:
Czy poprawnym jest zadeklarowanie funkcji wirtualnej z klasy podstawowej o sygnaturze

virtual A* clone() const

W klasie pochodnej jako:

virtual B* clone() const

Czyli z innym typem zwracanym, tak aby to nie było żadne przesłonięcie tylko wirtualność dalej dobrze działała?

Generalnie sprawdziłem to i wydaje się być w porządku, ale nigdy się z czymś takim nie zetknąłem. Na zdrowy chłopski rozum wydaje się, że istnienie takiej możliwości nie powinno być problemem. Wydaje mi się natomiast, że chyba nie raz czytałem, że metoda implementująca powinna mieć taką samą sygnaturę jak metoda implementowana, także nie wiem czy jest to zgodne ze standardem.

Pozdrawiam,
Platyna

0

To się nie powinno skompilować. Nie można tak robić.

0

Kompiluje się i działa doskonale. Przykładowy kod:

#include <cstdio>

class A {
  public:
	virtual A* clone() const {
	  printf("A\n");
	  return new A;
	}
};

class B : public A {
  public:
	virtual B* clone() const {
	  printf("B\n");
	  return new B;
	}
};

class C : public B {
  public:
	virtual C* clone() const {
	  printf("C\n");
	  return new C;
	}
};

int main() {
  A* a;
  
  a = new A;
  a->clone();
  
  a = new B;
  a->clone();
  
  a = new C;
  a->clone();
  
  B* b;
  B* p = new C;
  b = p->clone();
  
  return 0;
}
0

Rzeczywiście. Powinno być ok. Zapomniałem o kowariancji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1