Program (zadanie) - uwagi

0

Witam.

Na uczelni miałem takie zadanie:

Napisać klasę SprzetRTV posiadającą funkcje:

  • konstruktor pobierający nazwę urządzenia i zapamiętujący ją w klasie
  • nazwa () - zwraca zapamiętaną nazwę urządzenia
  • wlacz() i wylacz() - włączają i wyłączają urządzenie (odpowiednio)
  • graj() - wyświetla na ekranie nazwę urządzenia (uzyskana za pomocą funkcji nazwa()) i tekst "gra", o ile sprzęt jest włączony.
    Dodać klasę Radio dziedziczącą po klasie SprzetRTV. Klasa ta różni sie tym od klasy bazowej, że jej funkcja nazwa zwraca tekst "Radio" oraz nazwę urządzenia, na przykład, jeżeli do konstruktora przekazalibyśmy parametr "Grundig", funkcja nazwa() powinna zwrócić tekst "Radio Grundig".

Zrobiłem to w ten sposób : http://pastebin.com/3jfc10SC

Sprawdzający odrzucił to rozwiązanie wpisując uwagę: "czy funkcja nazwa musi być funkcja wirtualną zadeklarowaną w klasie bazowej?"
Dwa pytania do Was:

  • Czy użycie w tym miejscu funkcji wirtualnej czemuś szkodzi ?
  • Jak w inny sposób zrobić tak aby funkcja graj() wywołana z obiektu klasy Radio zwróciła "Gra Radio Grudig" ?

Pozdrawiam

0

na pierwsze
I tak i Nie

Funkcja powinna byc CZYSTO wirtualna. Czyli taka. Wtedy wymusza sie napisanie funkcji nazwy przez klasy pochodne

virtual string nazwa() = 0;

na drugie
uzyj polimorfizmu

1

Użycie w klasie SprzetRTV funkcji czysto wirtualnej było by nie zgodnie z treścią zadania ("Napisać klasę SprzetRTV posiadającą funkcje: - nazwa () - zwraca zapamiętaną nazwę urządzenia").
"Użyj polimorfizmu" - a czy użycie funkcji wirtualnej i przesłonięcie jej to nie jest własnie to ? (http://www.p-programowanie.pl/cpp/polimorfizm-metody-wirtualne/#Przykad-zastosowania-polimorfizmu)

0

no to nie powinna byc wirtualna w takim razie. Bo nie ma sensu robic tutaj wirtualnie i zeby celowo przeslaniac funkcje. Ten przyklad sam w sobie jest dziwny... Moglbys uzyc tutaj polimorfizmu uzywajac wskaznika na rtvagd majac tam radio i wywolujac nazwa bylaby wywolana dobra nazwa. Ale to nie tedy droga.

Przeslanianie funkcji to nie polimorfizm

http://www.tutorialspoint.com/cplusplus/cpp_polymorphism.htm
Tu masz przyklad polimofrizmu. Masz wkasnik typu Shape i jest przypisany do niego obiekt Triangle!
wywolujac ten wskaznik. wywolujesz jakas funkcje z klasy Shape, ale jezeli jest ona wirtualna to bedzie szukac AKTUALNEGO TYPU (Czyli wowla Triangle)

0

Nie bardzo wiem jak to wykorzystać w tym przykładzie...
Tworząc wskaźnik typu SprzetRTV przypisany do obiektu typu Radio wywołując metodę Graj() otrzymuje "Grundik gra" (więc nie to co bym chciał) .

0

czy funkcja nazwa musi być funkcja wirtualną zadeklarowaną w klasie bazowej?

Nie musi, możesz w konstruktorze radia dodawać "Radio ". Przy okazji, Twój konstruktor jest zły, bo pobiera dane od użytkownika, zamiast użyć parametru.

Btw, zamiast funkcji wirtualnych możesz użyć polimorfizmu statycznego z CRTP, tylko wtedy SprzetRTV nie będzie naprawdę klasą ;)

template<typename T = void>
struct SprzetRTV {

	SprzetRTV(std::string const& n) : nazwa_(n), wlaczone_{} {}

	string nazwa() const { return static_cast<T const*>(this)->nazwaImpl(); }

	void wlacz() { wlaczone_ = true; }
	void wylacz() { wlaczone_ = false; }

	void graj() {
		if(wlaczone_){
			cout << nazwa() << " gra" << endl;
		}
	}

protected:
	string nazwaImpl() const { return nazwa_; }

	string nazwa_;

	bool wlaczone_;
};

template<>
struct SprzetRTV<void> : SprzetRTV<SprzetRTV<void>> {
	using SprzetRTV<SprzetRTV<void>>::SprzetRTV;
};

struct Radio : SprzetRTV<Radio> {
	using SprzetRTV<Radio>::SprzetRTV;

	string nazwaImpl() const {
		return "Radio " + nazwa_;
	}
};

int main()
{
	SprzetRTV<> foo("foo");
	DBG(foo.nazwa());
	foo.graj();
	foo.wlacz();
	foo.graj();

	cout << string(80, '=') << endl;

	Radio bar("bar");
	DBG(bar.nazwa());
	bar.graj();
	bar.wlacz();
	bar.graj();

}

http://melpon.org/wandbox/permlink/fV3Sf8RknVUM3ASC

0

Nie wiem czy Cię dobrze zrozumiałem, ale dodanie konstruktora w Radio który podmieni wprowadzoną nazwa z "Grundig" na "Radio Grundig" mimo że zadziała poprawnie (późniejsze funkcje wyświetlą to co bym chciał) chyba nie będzie zgodne z treścią (bo mowa jest o zmianie funkcji nazwa()).

" Przy okazji, Twój konstruktor jest zły, bo pobiera dane od użytkownika, zamiast użyć parametru."
zrobiłem tak sugerując się treścią: "- konstruktor __pobierający __nazwę urządzenia i zapamiętujący ją w klasie" ;)

A co do drugiej części to muszę to przeanalizować i zrozumieć - ale wątpię żeby o to chodziło prowadzącemu ;)

0

Pobierający - z parametru, tak ja to zrozumiałem, ale może znasz wykładowcę bardziej i masz rację. Ale jeśli tak jest to nie znam innej metody niż metody wirtualne/CRTP

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