Dědičnost

12. díl - Dědičnost

Petr Sklenička       24. 7. 2011       C++/C       8221 zobrazení

Náplní tohoto dílu je dědičnost. Je zde tedy vysvětleno, co to dědičnost je, kdy je vhodné ji použít, jaké jsou její druhy a jaká je její syntaxe. Mimo to jsou lehce zmíněny i konstruktory a destruktory a způsob, jak lze třídy organizovat do souborů.

Jako obvykle, i tento díl začne stručným shrnutím toho, co jsme se naučili v díle předchozím. Nyní byste tedy měli rozumět pojmům konstruktor, destruktor a modifikátory přístupu. Samozřejmě byste také měli umět konstruktor a destruktor napsat a v každé třídě vhodně zvolit pro jednotlivé atributy a metody to, zda budou privátní či veřejné.

Dnes na předchozí díl navážeme dědičností. Dovíte se tedy, co to dědičnost je, proč jí používáme, jaké jsou druhy dědičnosti atd. Vysvětlíme si také modifikátor přístupu protected.

Co je to dědičnost?

Pokud jste četli minulý díl (já pevně doufám, že ano), jistě máte napsanou naší třídu Zamestnanec. Jistě se mnou budete souhlasit, když řeknu, že zaměstnanec je dosti široký pojem. Zaměstnancem může být kdokoliv – uklízečka, sekretářka, programátor, revizor, dělník apod. Pokud budeme chtít v našem programu nějakým zásadnějším způsobem rozlišit, o jakého zaměstnance se jedná, budeme muset napsat každou třídu zvlášť – tedy jednu pro uklízečku, druhou pro sekretářku atd.

Mějme však stále na paměti, že se pořád jedná o zaměstnance. Nepochybně je také pravda, že každý zaměstnanec má svoje jméno, svůj plat, počet let praxe apod. To jsou obecné věci, které má každý zaměstnanec, bez ohledu na to, jakou práci vykonává. Samozřejmě najdeme ale i věci, které už jsou pro každou profesi individuální – dělník může mít atribut, podle kterého poznáme, v jaké části továrny pracuje, u programátora můžeme evidovat, v jakém jazyce nejčastěji programuje atd.

Co jsem tedy chtěl výše uvedenými odstavci naznačit? Nic jiného než to, že pokud bychom psali třídu pro každý druh zaměstnance, určitě by se nám některé atributy a metody opakovali – psali bychom je vícekrát, přitom by dělaly to samé. To je bezesporu značně nevýhodné – úplně zbytečně budeme mít mnohem delší kód. No a čím delší kód máme, tím máme více prostoru na to, abychom v něm nasekali více chyb. Pokud bychom si i přesto dali tu práci a kód tímto špatným způsobem napsali, další problémy se nám ani tak nevyhnou. Pokud budeme například chtít u zaměstnance zavést nový atribut (např. telefonní číslo), budeme muset tento atribut dopsat do všech tříd, které reprezentují nějaký konkrétní druh zaměstnance. To samé platí, pokud budeme chtít nějaký atribut odebrat – opět musíme projít všechny třídy a atribut několikrát smazat.

Jak tedy řešit všechny tyto problémy? Asi každého podle nadpisu tohoto dílu napadne, že tajemství je ukryto v použití dědičnosti.

Nejlepším vysvětlením bude asi příklad s názornou ukázkou. Dejme tomu tedy, že chceme vytvořit třídu Programator. Položme si tedy nyní otázku – je programátor zaměstnanec? Má programátor jméno, plat, počet let praxe atd? Samozřejmě že ano. Naše třída zaměstnanec už všechny tyto atributy má, čili není nutné je psát znovu. O všechno, co potřebujeme, se postará následující zápis:

class Programator : public Zamestnanec
{
    

};

Tím říkáme následující – třída Programator dědí (veřejně) z třídy Zamestnanec. To znamená, že  třída programátor nyní obsahuje všechny metody a atributy, jako třída Zamestnanec. To, jestli jsou tyto zděděné metody a atributy veřejné, chráněné či privátní je věc druhá, na kterou se za okamžik podíváme.

Jak organizovat třídy do souborů

Nejprve bych ale rád udělal malou odbočku, protože někoho z Vás možná napadla otázka, kam vlastně tuto novou třídu napsat – tím myslím do jakého souboru. Možností je více. Ta nejjednodušší, nejpohodlnější, ale zároveň ne příliš vhodná možnost je napsat tuto třídu pod třídu Zamestnanec, čili do souboru Zamestnanec.h.

Druhou možností, kterou jsem v tomto případě také použil, je vytvořit nový soubor s názvem Programator.h a třídu napsat do něj. Samozřejmě nesmíme zapomenout v tomto souboru úplně nahoru napsat

#include "Zamestnanec.h"

V souboru main.cpp pak už stačí nahoře mít jen

#include "Programator.h"

Pak bude vše fungovat jak má a zároveň budeme mít třídy samostatně v jednotlivých souborech, což nám pak pomůže v rychlejší orientaci v celém projektu.

Pokud Vám ani tento způsob nevyhovuje, můžete také oddělit těla metod od zbytku třídy. Tím myslím následující: v hlavičkovém souboru budete mít pouze třídu, v níž napíšete její atributy, ale u metod nebudete psát jejích tělo, napíšete pouze jejich “hlavičku” a ukončíte středníkem. V nějakém jiném .cpp souboru pak implementaci těchto metod doplníte. Mohlo by to vypadat zhruba takto:

class NejakaTrida
{
    private:    
        int atribut1, atribut2;
    public:
        NejakaTrida();                    // Konstruktor
        int Metoda1(int p1, int p2);    // Priklad nejake metody
};
#include "NejakaTrida.h"

NejakaTrida::NejakaTrida()
{
    // telo konstruktoru
}

int NejakaTrida::Metoda1(int p1, int p2)
{
    // telo metody
    return p1 * p2;
}

Vidíte, že v tomto případě vždy nejprve píšeme návratový typ metody (u konstruktoru žádný není), poté název třídy a přes dvojtou dvojtečku přistoupíme k potřebné metodě.

Po malé odbočce, ve které jsme si udělali jasno, jak třídy organizovat do souborů, se nyní vrátíme zpět k dědičnosti.

Modifikátory přístupu a dědičnost

Bez velké námahy máme v tuto chvíli napsanou třídu Programator. Doplníme do ní další atribut, podle kterého poznáme, jaký programovací jazyk programátor nejčastěji používá. Dopíšeme ji také konstruktor, ve kterém mimo jiné nastavíme hodnotu tohoto atributu.

class Programator : public Zamestnanec
{
    private:    
        string progJazyk;
    public:
        Programator(int rokNar, int praxe, int plat, string jm, bool _jeMuz, string jazyk)
        {
            rokNarozeni = rokNar;
            pocetLetPraxe = praxe;
            vysePlatu = plat;
            jmeno = jm;
            jeMuz = _jeMuz;
            progJazyk = jazyk;
        }
};

Pokud píšete kód ve Visual Studiu, pravděpodobně se Vám, stejně jako mě, prvních pět atributů (tedy těch zděděných) podtrhlo červeně a kód ani nelze zkompilovat. V čem je tedy problém a jak ho řešit?

Řešení je velmi snadné a rychlé. Ve třídě Zamestnanec změňte modifikátor přístupu private na protected. Teď už by červené podtržení atributů mělo zmizet, ale kód zkompilovat ještě nepůjde. Ve třídě Zamestnanec chybí bezparametrický, defaultní konstruktor – proto jej dopište, v těle klidně nemusí být vůbec nic. Jde o to, že jakmile jsme vytvořili konstruktor s parametry, defaultní bezparametrický konstruktor si již C++ nevytvoří. Teď už by kompilace měla proběhnout bez problémů.

Je však třeba udělat pořádek v tom, jak to vlastně s těmi modifikátory přístupu v souvislosti s dědičností je, proto se podívejte na následující tabulku.

Typ dědičnosti_____________
Typ atributu (metody)
Soukromá dědičnost Chráněná dědičnost Veřejná dědičnost
soukromý (private) položky budou přístupné jen přes základní třídu položky budou přístupné jen přes základní třídu položky budou přístupné jen přes základní třídu
chráněný (protected) soukromé položky chráněné položky chráněné položky
veřejný (public) soukromé položky chráněné položky veřejné položky

Nejprve se pořádně podívejte na poslední sloupec, který se vztahuje k veřejné dědičnosti, kterou jsme použili i my v našem příkladu. Tabulka nám říká, že privátní atributy třídy Zamestnanec budou ve třídě Programator přístupné pouze přes základní, čili bázovou třídu – třídu Zamestnanec. Chráněné a veřejné položky zůstanou stejné – tedy chráněné chráněnými a veřejné veřejnými. To tedy vysvětluje, proč byly atributy podtrženy červeně předtím, než jsme v bázové třídě změnili jejich modifikátor přístupu.

Soukromá a chráněná dědičnost

Z tabulky jste jistě sami pochopili, že v C++ není pouze veřejná dědičnost, ale také soukromá a chráněná. V tomto díle se jí nebudu dále zabývat, protože se používá velmi zřídka. Ukážu jen její zápis, který ale není nijak složitý – stačí pouze změnit klíčové slovo public na jiné.

class Programator : protected Zamestnanec // Chráněná dědičnost
class Programator : private Zamestnanec // Soukromá dědičnost

Ještě bych rád zdůraznil, že v případě použití veřejné (public) dědičnosti je nutné klíčové slovo public uvést, protože jinak Vám kompilátor nezahlásí chybu, ale použije soukromou dědičnost, což může vést k dost dlouhému hledání chyby.

Jak je to s voláním konstruktorů?

Další věcí, kterou je nutno vědět, je způsob, jak se při použití dědičnosti a následném vytváření objektů volají konstruktory. Pro jednoduchost předpokládejme třídy A, B, C, přičemž třída C dědí ze třídy B, která zase dědí z třídy A. Pokud poté vytvoříme instanci třídy C, nezavolá se jen konstruktor třídy C, ale zavolá se i konstruktor třídy A  a B a to v následujícím pořadí:

  1. Nejprve se volá konstruktor třídy A
  2. Pak konstruktor třídy B
  3. Nakonec konstruktor třídy C

Jednoduše řečeno, pokud nějaká třída dědí z jiné třídy, a ta zase z jiné, vždy se konstruktory volají podle hierarchie dědičnosti.

Přesně naopak se volají destruktory. Dochází-li k ukončení platnosti objektu třídy C, zavolá se destruktor třídy C, pak destruktor třídy B a nakonec destruktor třídy A.

Obě tyto skutečnosti si můžete jednoduše ověřit. Stačí si napsat jednoduché třídy a do jejich konstruktorů (destruktorů) napsat kód, který pouze vypíše nějakou hlášku – sami uvidíte, v jakém pořadí budou jednotlivé hlášky vypsány.

Vícenásobná dědičnost

Stejně okrajově, jako jsem zmínil chráněnou a soukromou dědičnost, zmíním i vícenásobnou dědičnost. Nejde o nic jiného než o to, že daná třída dědí z více tříd najednou – tedy třída A bude současně dědit z třídy B a C. Syntaxe je následující:

class A : public B, public C

Samozřejmě i v tomto případě je možno použít chráněnou či soukromou dědičnost. Vícenásobná dědičnost je však také málo používaná věc, neboť je s ní spjato mnoho problémů – například dědění metod stejného názvu z více tříd. Pokud někdo máte zkušenosti například s jazykem Java, určitě více, že tam vícenásobná dědičnost neexistuje, stejně jako v jazyce C#. Tyto jazyky ale mají jinou věc, kterou C++ nedisponuje – tzv. rozhraní, které je oproti vícenásobné dědičnosti v C++ používáno celkem často.

Zpátky k veřejné dědičnosti

Po dvou menších odbočkách se opět vrátíme k dědičnosti, která se v C++ nejčastěji používá. Známe již syntaxi jak dědičnost zapsat a víme, co to vlastně je a jaké jsou výhody. Dále máme napsán i konstruktor odvozené třídy Programator, takže nám nic nebrání v tom, abychom si vytvořili objekt této třídy a zavolali nějaké metody.

int main()
{
    Programator p(1985, 4, 32000, "Jan Krysa", true, "C++");

    cout << "Programator " << p.VratJmeno() << " ma plat " << p.VratPlat() << ".\n";
    return 0;
}

Je možné, že metodu VratJmeno() nemáte napsanou, proto si ji dopište – samozřejmě do třídy Zamestnanec, třída Programator ji zdědí.

Sami již vidíte, že naše třída Programator, kterou jsme napsali bez velkého úsilí, umí to, co třída Zamestnanec, a navíc u ní máme atribut progJazyk.

Předpokládám, že v tuto chvíli by Vám dědičnost neměla být úplně cizí, ale možná Vám bude nějakou dobu trvat, než si s ní trochu více porozumíte. Vždy je důležité také zvážit, zda se vůbec dědičnost hodí použít. Obecně vzato platí, že pokud je daná třída jakýmsi specifickým upřesněním jiné třídy, jde o vztah dědičnosti. V našem případě to samozřejmě platí – programátor je specifickým druhem zaměstnance. Stejně tak je například čtverec specifickým druhem geometrického obrazce. Zkusme ale například vzít vztah dveře a okno. Hodí se zde dědičnost? Někdo by řekl, že obojí se dá otevřít a zavřít, klidně mohou mít stejnou barvu, ale ani přesto bych v tomto případě dědičnost nepoužil. Dveře nejsou specifickým upřesněním okna, což neplatí ani naopak. Jiná věc by byla, vytvořit třídu, která by reprezentovala nějaké věci v bytě a od té pak podědit dveře a okno. Mezi dveřmi a oknem je však použití dědičnosti krajně nevhodné. Možná se smějete, že jsem uvedl zcela banální příklad a že to je přece jasné, kdy dědičnost použít a kdy ne, ale v některých případech to až tak jasné není.

Pro dnešní díl je to vše. Měli byste nyní vědět, co je to dědičnost, jaká je její syntaxe, jaké jsou její druhy a měli byste mít alespoň nějaké základní povědomí o tom, ve kterých případech ji použít. V příštím díle budeme stále ještě s dědičností pracovat, v krátkosti se ještě vrátíme ke konstruktorům a pak se k nám vrátí pointery, ne však na primitivní datové typy, ale pointery na objekty. Také se budeme věnovat virtuálním metodám.

 

hodnocení článku

1 bodů / 1 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Všechny díly tohoto seriálu

 

Mohlo by vás také zajímat

C++/CLI a interoperabilita managed a unmanaged kódu - díl 1.: Úvod do jazyka a základní konstrukce

V tomto článku je popsána nadstavba C++ pro práci s .NET prostředím zvaná C++/CLI umožňující vytvářed mixed assembly obsahující jak managed tak unmanaged kód. V prvním díle je popsána myšlenka jazyka a základní syntaktické konstrukty (základní typy, podmínky, cykly, pole, namespace a část tříd a objektů). U čtenáře je předpokládána znalost .NET frameworku a nativního programování nejlépe v C++ (alespoň syntaxi a základy).

C++/CLI a interoperabilita managed a unmanaged kódu - díl 2.: Složitější konstrukty, low-level přístup a generické programování

V tomto článku je popsána nadstavba C++ pro práci s .NET prostředím zvaná C++/CLI umožňující vytvářed mixed assembly obsahující jak managed tak unmanaged kód. V tomto díle jsou popsány pokročilejší partie jazyka týkající se hlavně objektů, low-level přístupu k managed objektům a generického programování.

Virtuální souborový systém

Článek pojednává o způsobu návrhu virtuálního souborového systému. Před čtením Vám doporučuji stáhnout si a přečíst zadání, abyste věděli o co vlastně jde. Ke stažení jsou i zdrojové kódy v jazyce C++. Aplikace asi nemá žádné velké využití, nicméně přišlo mi to jako zajímavý problém - jednalo se o semestrální projekt.

 

 

Nový příspěvek

 

Diskuse: Dědičnost

Kedy bude dalsi clanok? predsa su to uz 4 mesiace :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nemůžu to slíbit, ale budu se snažit, abych ho napsal do konce ledna, nebo někdy začátkem února. Za tu velkou pauzu se čtenářům omlouvám, je to zapříčiněno jednak nedostatkem času, ale abych se nevymlouval jen na čas, jistou roli v tom hraje i moje lenivost... Nicméně pauza už byla opravdu velká, takže se budu snažit další díl napsat co možná nejdříve.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

pocuj mohol by si mi skontorlovat jeden jednoduchy program? (je to moj prvy samostatny program taka jednoducha kalkulacka) ale nejde mi to skompilovat pise mi nejaku chybu pri kompilacii nieco so suborom menu.h moze byt ze som aj uvazoval zle no chybu mi vypisuje len v tom subore este to chcem otestovat ale neviem prist na to co za chyba tam je :(

menu.h:

#include <iostream>
using namespace std;
int menu();
int Scitanie(int x, int y);
int Odcitanie(int a, int b);
int Nasobenie(int c, int d);
int Delenie(int e, int f);

int menu();
{
	int volba;
	cout << "****MENU****\n";
	cout << "(1) Scitanie\n";
	cout << "(2) Odcitanie\n";
	cout << "(3) Nasobenie\n";
	cout << "(4) Delenie\n";
	cout << "(0) Koniec\n";
	cin >> volba;
	return volba;
}

delenie.h

int Delenie(int e, int f)
{
	int podiel;
	cout << "Vlozte 2 cisla:\n";
	cout << "Delenec:"; cin >> e;
	cout << "\nDelitel:"; cin >> f;
	if (f == 0)
	{
		cout << "\nDelenie 0 nieje mozne!!\n";
		return podiel = -1;
	}
	else
	{
	return podiel = e/f;
	}
}

nasobenie.h:

int Nasobenie(int c, int d)
{
	int sucin;
	cout << "Vlozte 2 cisla:\n";
	cout << "Cinitel 1.:"; cin >> c;
	cout << "\nCinitel 2.:"; cin >> d;
	return sucin = c*d;
}

scitanie.h:

int Scitanie(int x, int y)
{
	int sucet;
	cout << "Vlozte 2 cisla:\n";
	cout << "Scitanec 1.:"; cin >> x;
	cout << "\nScitanec 2.:"; cin >> y;
	return sucet = x+y;
}

odcitanie.h:

int Odcitanie(int a, int b)
{
	int rozdiel;
	cout << "Vlozte 2 cisla:\n";
	cout << "Cislo 1.:"; cin >> a;
	cout << "\nCislo 2.:"; cin >> b;
	return rozdiel = a-b;
}

kalkulacka.cpp:

#include <menu.h>
#include <scitanie.h>
#include <odcitanie.h>
#include <nasobenie.h>
#include <delenie.h>
using namespace std;

int main()
{
	int menu();
	int f_Koniec == false;
	while (!f_Koniec)
	{
		if (volba < 0 && volba > 5)
		{
			cout << "Neplatna volba!!\n";
			continue;
		}
		switch (volba)
		{
		case 1:
			Scitanie(int x, int y);
			cout << "Sucet:" << sucet << "\n";
			break;
		case 2:
			Odcitanie(int a, int b);
			cout << "Rozdiel:" << rozdiel << "\n";
			break;
		case 3:
			Nasobenie(int c, int d);
			cout << "Sucin:" << sucin << "\n";
			break;
		case 4:
			Delenie(int e, int f);
			cout << "Podiel:" << podiel << "\n";
			break;
		case 0:
			f_Koniec = true;
			cout << "\nKoniec programu....";
			break;
		deafult:
			cout << "Neplatna volba!!\n";
			continue;
		}
	}
	return 0;
}

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

V rychlosti jsem na to mrknul a těch chyb tam bude určitě více. Doporučuji Vám podívat se na to, jakým způsobem se volají funkce a jak se pracuje s tím, co daná funkce vrací. Jen pro ukázku:

int vysledek = Delenie(10, 2); // toto je spravne

Zápis Delenie(int e, int f) je v tomto případě zcela mimo. Uvědomte si, že funkce něco vrací, Vy to nikam (tu hodnotu) nepřiřazujete. Dále funkci musíte předat parametry, což se určitě nedělá tak, jak se to snažíte dělat.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

ano bolo tam viac chyb :) som si to vsimol az neskor pretoze doteraz som pouzival dev c++ a toto som robil vo MC VS a tam je ten vypis trosku iny (pozrel som len na cislo pri "failed") a nevsimol som si tu kopu chyb trosku vysie :) uz pracujem na oprave zredukovane na 4 chyby este prist na to co tam treba spravit a otestovat to :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

takze dostal som sa sem:

#include <iostream>
using namespace std;

int menu(int volba);
int odcitanie (int a, int b);
int nasobenie(int c, int d);
int delenie (int e, int f);
int scitanie(int x, int y);

int main()
{
	int volba;
	int x;
	int y;
	int a;
	int b;
	int c;
	int d;
	int e;
	int f;
	int f_Koniec = false;
	while (!f_Koniec)
	{
		volba = menu(volba);
		if (volba < 0 && volba > 5)
		{
			cout << "Neplatna volba!!\n";
			break;
		}
		switch (volba)
		{
		case (1):
			int sucet;
			cout << "Vlozte 2 cisla:\n";
			cout << "Scitanec 1.:"; cin >> x;
			cout << "\nScitanec 2.:"; cin >> y;
			sucet = scitanie(x,y);
			cout << "Sucet:" << sucet << "\n";
			break;
		case (2):
			int rozdiel;
			cout << "Vlozte 2 cisla:\n";
			cout << "Cislo 1.:"; cin >> a;
			cout << "\nCislo 2.:"; cin >> b;
			rozdiel = odcitanie(a,b);
			cout << "Rozdiel:" << rozdiel << "\n";
			break;
		case (3):
			int sucin;
			cout << "Vlozte 2 cisla:\n";
			cout << "Cinitel 1.:"; cin >> c;
			cout << "\nCinitel 2.:"; cin >> d;
			sucin = nasobenie(c,d);
			cout << "Sucin:" << sucin << "\n";
			break;
		case (4):
			int podiel;
			cout << "Vlozte 2 cisla:\n";
			cout << "Delenec:"; cin >> e;
			cout << "\nDelitel:"; cin >> f;
			podiel = delenie(e,f);
			cout << "Podiel:" << podiel << "\n";
			break;
		case (0):
			{
			f_Koniec = true;
			cout << "\nKoniec programu....";
			break;
			}
		default:
		{
			cout << "Neplatna volba!!\n";
			continue;
		}
	}
	return 0;
}
}

int menu(int volba)
{
	cout << "****MENU****\n";
	cout << "(1) Scitanie\n";
	cout << "(2) Odcitanie\n";
	cout << "(3) Nasobenie\n";
	cout << "(4) Delenie\n";
	cout << "(0) Koniec\n";
	cin >> volba;
	return volba;
}

int scitanie(int x, int y)
{
	return x+y;
}

int odcitanie(int a, int b)
{
	return a-b;
}

int nasobenie(int c, int d)
{
	return c*d;
}

int delenie (int e, int f)
{
	if (f == 0)
	{
		cout << "\nDelenie 0 nieje mozne!!\n";
		return -1;
	}
	else
	{
		return e/f;
	}
}

ale je tu jeden problem vsetko je skompilovane (da sa to spustit hoci...) ale vyskakuje mi po kompilacii jedno varovanie: "(24) : warning C4700: uninitialized local variable 'volba' used"

...a absolutne neviem co to varovanie znamena (predpokladam ze tie funkcie su uz spravne no aspon okrem funkcie menu() kde sa pouziva premenna "volba")

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Otázkou je, proč do funkce menu předáváte parametr volba. Ta chyba je způsobena tím, že té funkci předáte proměnnou volba, která ale v tu chvíli ještě nemá žádnou přiřazenou hodnotu. Tu funkci upravte tak, aby nebrala žádný parametr, pak jí nebudete nic předávat a varování bude pryč a v lepším případě to bude dokonce i fungovat.

Jinak ještě k tomu dělení - máte tam všude int, což je celočíselný datový typ, takže pokud funkci předáte například čísla 5 a 2, dostanete špatný výsledek.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

ok upravil som to program funguje ako ma ale chcem sa spytat preco ta funkcia musi byt bez parametru? to trosku nechapem a dakujem :)

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Myslím si, že by jste se měl učit programovat s jiným jazykem, jak tak koukám na váš kód, tak je jen otázkou času, než si ustřelíte nohu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak ona samozřejmě nemusí být bez parametru, ale v tomto případě je to zbytečné. Funkce vám vrací hodnotu proměnné volba, která ale není nijak závislá na tom, co funkci předáte. Vaše funkce menu vyzývá uživatele k tomu, aby něco zadal a podle toho funkce vrací rozdílné hodnoty. Ty ale nejsou nijak závislé na tom, co funkci předáte jako parametr. Proto tedy ve Vašem kódu není parametr ve funkci volba potřeba.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

aha dakujem :) a k tomu predoslemu prispevku (nie vasemu) by som povedal len tolko ze toto bol moj prvy program takze to netreba brat az tak zle (dufam) :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Samozřejmě, že není třeba brát to až tak zle. Je sice pravda, že v tom kódu bylo dost chyb, ale programování se člověk nenaučí ze dne na den, chce to čas. Proto bych neházel flintu do žita a to, že si máte vybrat na začátek jiný jazyk, o tom by se dalo debatovat. Je hodně lidí, co tvrdí, že C++ je těžkopádné a pro začátečníky se nehodí, nicméně toto jsou beztak jen základy a ty jsou víceméně stejné všude. Krom toho naučíte-li se C++, nebude Vám dělat větší problém přejít třeba na Javu nebo C#.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

samozrejme ze najjednoduhsie je zacat pascalom ale kedze som zacal s programovanim dost neskoro (vzdy som si myslel ze ma to na skole naucia no mylil som sa) a teraz by to bolo treba nejako urychlit tak som pascal (ktory sa aj tak nepouziva) preskocil a siel rovno na C++ ja chapem ze zaciatky su tazke ale vzdat sa nemienim :) jednoducho neexistuje zabavnejsia praca nez v hernom priemysle :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak začít s Pascalem rozhodně není nejjednodušší, to se jenom říká, ale taky jsou jednodušší jazyky. Ono jde ale hlavně o to, že C++ má spoustu "featurek", které těď v žádném případě nevyužijete, akorát vás budou otravovat, neříkám, že C++ je špatný jazyk pro začátek, sám jsem s ním začínal a právě proto to mohu zpětně posoudit. Budete používat spoustu věcí, kterým nerozumíte, jenom proto, že tam "mají být". Mně je celkem jedno, jestli u C++ zatím zůstanete, to je koneckonců vaše věc, já vám jen říkám, jak to vidím já.

Co bych vám poradil, když zůstanete u C++?

1) Odnaučte se takto debilně pojmenovávat proměnné, je to strašný zlozvyk, kterého se budete těžko zbavovat.

2)Deklarujte proměnné až ve chvíly, kdy jsou poprvé potřeba.

3)Pokud používáte proměnné jako parametry mohou se jmenovat stejně, je zbytečné dávat jim jiná jména, mám na mysli toto:

//Nevhodně

int scitanie(int x, int y)
{
	return x+y;
}

int odcitanie(int a, int b)
{
	return a-b;
}

int nasobenie(int c, int d)
{
	return c*d;
}

int delenie (int e, int f)
{
	if (f == 0)
	{
		cout << "\nDelenie 0 nieje mozne!!\n";
		return -1;
	}
	else
	{
		return e/f;
	}
}

//Lepší, přehlednější
int scitanie(int a, int b)
{
	return a+b;
}

int odcitanie(int a, int b)
{
	return a-b;
}

int nasobenie(int a, int b)
{
	return a*b;
}

int delenie (int a, int b)
{
	if (a == 0 || b == 0)
	{
		cout << "\nDelenie 0 nieje mozne!!\n";
		return -1;
	}
	else
	{
		return a/b;
	}
}

Tu funkci pro dělení by šlo napsat i kratší, třeba takto:

int delenie (int a, int b)
{
   return (b == 0) ? 0 : a / b;
}

4) U matematických operací je lepší používat typ double místo int.

Neberte to jako nadávání čí tak něco, snažím se vám poradit, jak se v tom neztratit ;)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tak zatial dakujem za rady :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Dědičnost

V clanku je chyba - trida Programator neni upresnenim tridy Zamestnanec. Je to uplne samostatna trida a zajimalo by mne, co by autor delal, pokud by mel programatora najmout na smlouvu ci od jine firmy a nebo by to byl jeho rodinny prislusnik.

Dedeni je velmi velmi osemetna vec (a zacinajicimi programatory dost precenovana) a zrovna vztah Zamestnanec-Programator by se timhle urcite neresil.

nahlásit spamnahlásit spam -3 / 3 odpovědětodpovědět

Vezměte v potaz následující fakt - tento seriál je určen začínajícím programátorům, tj. těm, kteří o OOP, dědičnosti a dalších věcech nic neví. Proto tady nehodlám řešit, co by kdyby, čili mi nepřijde adekvátní řešit, zda programátor pracuje na smlouvu o dílo, nebo je to brigádník nebo je z jiné firmy. Článek si klade za cíl osvětlit začínajícím programátorům pojem dědičnost a myslím si, že to článek splňuje. A proto trvám na tom, že v tomto případě je vztah dědičnosti zvolen správně.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Vy jste ale hnidopich, toto je seriál pro začátečníky, moc to řešíte... Jde o to, aby začátečníci pochopily, k čemu dědičnost je.

Navíc chyba to nění:

JE Programátor zaměstnanec? Ano je! Takže dědičnost se zde uplatnit může, ano nemusí, ale není to chyba :-)

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

No jestli to zacnou chápat z těhle příkladů.....

Z tvrzení Programátor je zaměstnanec vůbec neplyne, že všichni programátoři jsou zaměstnanci - a často vůbec nejsou. Dědičnost v tomhle příkladě je zcela mimo a je to chyba - zkuste to udělat do nějakého IS a následně řešit všechny problémy, co vám z vašeho nesprávného modelu vznikly.

http://stackoverflow.com/questions/57521...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pokusím se Vám to vysvětlit ještě jednou, zjevně to pořád nechápete (nebo možná ano, ale jenom chcete rýpat). Tento článek neřeší a nezabývá se vývojem IS ani návrhem architektury, ani podobných věcí, které s vývojem IS souvisí. Tento článek vysvětluje na triviálním příkladě co je to dědičnost a jaké jsou její výhody. Čtenář by tedy měl získat představu o tom, jak dědičnost funguje, jaká je její syntaxe, výhody apod.

O tom, jak správně navrhnout a implementovat informační systém článek nepojednává, to by se nakonec ani do jednoho článku nevešlo. Každopádně, když umíte tak dobře kritizovat, pak pro Vás jistě nebude problém o vývoji IS a zvolení správné hierarchie dědičnosti napsat nějaký ten článek. Ostatní si jej určitě rádi přečtou a něčemu se přiučí. A možná Vám ho i doplní o nějakou tu kritiku a Vy pak budete marně vysvětlovat, proč jste to v článku napsal tak a ne onak. Bude to ale zbytečné, vždy se najde někdo, kdo to prostě nebude chtít pochopit a bude pořád "otravovat".

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Prominte, ze jsem upozornil na to, ze vami zvoleny priklad nebyl moc vhodny - a vim, proc jsem to napsal. Pokud to povazujete za rypani misto upresneni, je to vas problem.

S kritikou si klidne si posluzte:

http://blog.vyvojar.cz/mstr/archive/2008...

http://blog.vyvojar.cz/mstr/archive/2008...

http://blog.vyvojar.cz/mstr/archive/2008...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Když se ale podíváte a srovnáte můj článek s těmi, které jste psal Vy, musíte vidět ten jasný rozdíl - můj článek vysvětluje, co to dědičnost je, kdežto ve Vašem případě už předpokládáte, že čtenář má již s dědičností zkušenosti a zaměřujete se na hierarchii dědičnosti v rámci informačních systémů.

Proto mi přišlo vhodnější ukázat dědičnost na velmi jednoduchém příkladu. Netvrdím, že ve velkém IS by se to takto řešilo, ale tvrdím, že pro pochopení dědičnosti to stačí.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pokud máte rád humor, rád bych podotkl, že můj článek se zaměřuje hlavně na to, jak opravit díla čtenářů vašeho článků :-).

Ale vážně: Nelíbil se mi v článku zavedený vztah Zaměstnanec-Programátor - vysvětlujete dědění na špatném příkladu. Nehodnotím, jak ho vysvětlujete. Tvrzení "Programátor je specifickým druhem zaměstnance" je nepravdivé a pro tento vztah platí to, co jste napsal pro okno a dveře. Jen jsem na to upozornil a první reakcí bylo obvinění z hnidopišství :-) - asi nemáte rád jakoukoliv výtku, byť dobře míněnou.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To vůbec není o tom, že by mi vadila výtka nebo nějaká kritika. To je o tom, že já s Vaší výtkou nesouhlasím, proto si obhajuji svůj názor. Kdybych věděl, že máte pravdu, pak bych to uznal, splést se může každý a zároveň nikdo neví všechno.

V tomto případě ale s Vámi nesouhlasím, trvám si na svém, nic víc v tom není. Kdybych v článku vysvětloval, jak správně navrhovat IS, Vaše připomínka by byla na místě a já bych na ní reagoval úplně jinak.

A o hnidopišství jsem já nemluvil, to byl někdo jiný, ale to je vedlejší.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Za to hnidopisstvi se vam omlouvám.

Ta vaše zatvrzelost přiznat, že vaše tvrzení o programátorovi je nepravdivé, je ale úsměvná. Snad si to čtenáři správně přeberou a nebudou dědičnost takto chybně používat - z praxe vím, že je to velmi častá chyba, převážně začátečníků naučených z podobných článků a školy. Obvykle pak používají dědičnost všude, kde jen trochu mohou. Kdysi jsem tím také prošel :-)

Mimochodem tvrdíte, že programátor je zaměstnanec (což může a nemusí být pravda), ale naprogramoval jste tvrzení, že 'každý programátor je zaměstnanec" (což je nepravda). Podle mne chybka, podle vás OK.

IMHO je fér na to čtenáře upozornit (což nijak nesnižuje přinos článku a dalších informací). Zkuste místo slova Programátor použít slovo Řidič, snad už vám to dojde, že tam žádná dědičnost být nemůže. A příště raději volte třeba obecné názvy tříd A a B a nebo se inspirujte tím odkazem na stackoverflow.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Nechme tedy na čtenářích, ať si to přeberou po svém. Zkusím ještě naposledy ve stručnosti shrnout to, co se Vám celou dobu snažím říct.

Přeneseme-li se z programování do reálného života, pak máte pravdu, programátor může, ale i nemusí být zaměstnanec. Vzhledem k tomu, že IS se navrhují pro něco z reálného života, dědičnost zaměstnanec - programátor by mohla být špatně. V článku však neberu v potaz to, jestli programátor pracuje jako nějaký externista, brigádník či něco podobného. Proto mi v tomto případě nepřijde můj příklad jako chybný. A dál už se o tom odmítám bavit, neboť to asi nikam nevede - každý z nás si bude tvrdit své.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Dědičnost

Musim říct, že opět velice kvalitní díl, vysvětleno je vše co začátečník potřebuje, já sice dědičnost znám, ale například na syntaxi v C++ jsem byl celkem zvědavý(protože v C++ přiliš neprogramuji), vysvětlil jste to velice dobře, líbí se mi, že stavíte na příkladech z minulých dílů, donutí to více lidi si to pročíst a trochu víc se to naučit :-)

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Díky, takový příspěvek do diskuse vždy potěší.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback