Předání proměnné z jedné třídy do druhé – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Předání proměnné z jedné třídy do druhé – C / C++ – Fórum – Programujte.comPředání proměnné z jedné třídy do druhé – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Anonym
~ Anonymní uživatel
429 příspěvků
15. 2. 2016   #1
-
0
-

Ahoj.

Mohl by mi tu někdo poradit jak jednoduše v C++ předat proměnnou z jedné třídy do druhé? Použil jsem k tomu extern, ale předpokládám, že to není "čisté" řešení. Druhý nápad je použít getter a setter, ale přiznám se, že v C++ přesně nevím jak na to. Moc děkuju za pomoc!

Nahlásit jako SPAM
IP: 212.79.110.–
Reklama
Reklama
Kit+11
Guru
15. 2. 2016   #2
-
0
-

#1 Anonym
Injektuj objekt jedné třídy do objektu druhé třídy.

Pokud však skutečně potřebuješ něco takového, tak se zamysli nad tím, zda máš správně zvolenou architekturu. Ta proměnná (atribut) patří do které z těch dvou tříd? Proč by měla být vidět v té druhé třídě? Není spíš lepší, aby objekt první třídy dělal pro objekt druhé třídy nějakou službu, při které ten atribut bude používat?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Anonym
~ Anonymní uživatel
429 příspěvků
15. 2. 2016   #3
-
0
-

#2 Kit
No v podstatě se jedná o třídu A, která slouží k vytáhnutí dat ze souboru a zpracování, resp. přiřazení hodnot k proměnným. Tzn. pokud je v souboru někde definováno, že počet jablek je 10, do proměnné pocetJablek se zapíše hodnota 10.

Třída B pak na základě této proměnné provede nějakou akci.

Tou sloužbou mám chápat jakože zavolání getPocetJablek()?

Nahlásit jako SPAM
IP: 212.79.110.–
Kit+11
Guru
15. 2. 2016   #4
-
0
-

#3 Anonym
Metoda getPocetJablek() by byla primitivním getterem, kterým se to často řeší. Třída A se tak stává anemickou, což je v OOP nežádoucí.

Objektové řešení však spočívá v tom, že i ta "nějaká akce", kterou jsi bezmyšlenkovitě hodil do další třídy B správně patří do třídy A. Například a->prezentujJablka(stdout).

A pak ještě existuje kompromisní řešení, ve kterém si třída A drží kolekci různého ovoce a stav si zjistíš a->getPocet(A.Jablko) nebo třeba a->getPocet("Jablko"). Pro některé případy to může být zajímavé, ale jindy zase ne.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Anonym
~ Anonymní uživatel
429 příspěvků
15. 2. 2016   #5
-
0
-

#4 Kit
Takže pokud to chápu správně, měl bych třídu A:

A.cpp

A::A()
{
}

A::~A()
{
}

void A::priradHodnoty()
{
	A instanceOfA;
	instanceOfA.setZraleJablko(true);
}

A.h

 

#ifndef A_H
#define A_H

class A
{
    public:
        A();
        virtual ~A();

        bool getZraleJablko() {return zraleJablko;}
    
        void setZraleJablko(bool zj) {zraleJablko= ZJ;}
 
    private:
        bool zraleJablko;
    
    private:
	static void priradHodnoty();
   
};

#endif // A_H

A ve třídě B bych pak mohl libovolně, po vytvoření instance třídy, používat getZralejablko? Je tento návrh cca správně?

Nahlásit jako SPAM
IP: 212.79.110.–
Kit+11
Guru
15. 2. 2016   #6
-
0
-

#5 Anonym
Podle mne je to stále chybně. V OOP by ses objektu neměl na nic ptát - neměly by v něm být žádné gettery. Tím pádem se i settery stanou zbytečnými, protože vše potřebné si objekt nastaví v konstruktoru. Pokud bys měl nějaký getter nebo setter, neměl by být public, ale privat.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Anonym
~ Anonymní uživatel
429 příspěvků
15. 2. 2016   #7
-
0
-

#6 Kit
Tomu moc nerozumím, napsal bys mi nějaký jednoduchý příklad v kódu, jak to myslíš?

Nahlásit jako SPAM
IP: 212.79.110.–
Kit+11
Guru
16. 2. 2016   #8
-
0
-

#7 Anonym
Máš tam metodu getZraleJablko(). Proč? K čemu ti ta hodnota bude? Potřebuješ ji vůbec k něčemu? Ideální je prostě její hodnotu nepotřebovat a metodu getZraleJablko() vyhodit jako zbytečnou. Ušetříš tím v třídě hromadu místa. 

class A {
    public:
        A();
        virtual ~A();

    private:
        bool zraleJablko;
    
    private:
	static void priradHodnoty();
};

Teď už stačí jen dopsat potřebné metody. Třída A však je však pouze písmeno a netuším, co by písmeno A mělo umět. Umí něco tvé písmeno A? Proč je v písmenu A zraleJablko? To je nabodnuto na špičce toho fontu? A co tam dělá?

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Anonym
~ Anonymní uživatel
429 příspěvků
16. 2. 2016   #9
-
0
-

#8 Kit
Třída A se jmenuje např. EvidenceJablek a slouží ke zpracování dat ze vstupního souboru. Vzniknou mi pak proměnné typu zraleJablko, puvodJablka, ... No a ve třídě StanovCenu pak potřebuju udělat jednoduchou IF podmínku, kde např. bude if (puvodJablka == CR){...}.

Takže pokud uvažujeme situaci výše, jak bych měl správně "zjistit" v té třídě StanovCenu hodnotu proměnné puvodJablka?

Nahlásit jako SPAM
IP: 212.79.110.–
BDS+2
Věrný člen
16. 2. 2016   #10
-
0
-

#8 Kit
Nechce se mi pročítat podrobně tahle diskuze a zjišťovat k čemu vlastně má třída A sloužit.

Ale nechápu Tvůj výklad toho, že vyhodíš getZraleJablko() a zároveň nastavíš zraleJablko jako private. Jak chceš z vnějšku zjistit jestli je to jablko zralé?

Nahlásit jako SPAM
IP: 185.69.69.–
Visual Studio C/C#/C++
(pouze samouk)
Kit+11
Guru
16. 2. 2016   #11
-
0
-

#10 BDS
Nijak. Prostě udělám tu třídu a zbytek programu tak, abych takovou informaci nepotřeboval. K čemu je ti informace o tom, jestli je jablko zralé? Pokud jen proto, abys zjistil, zda je možné to jablko utrhnout a následně ho chceš utrhnout, tak je lepší napsat metodu utrhniJablko(), která si uvnitř nejen zjistí stav jablka, ale pokud je zralé, tak ho i utrhne.

Tell, don't ask. Neptej se, ale poroučej.

Edit: Samozřejmě se podle mého stylu ta metoda nebude jmenovat utrhniJablko(), ale jen utrhni(). Volat se pak bude jablko->utrhni(), což vypadá velmi přirozeně.

V případě využití polymorfismu to bude vypadat ještě lépe: 

Ovoce ovoce = new Jablko();
ovoce->utrhni();

Kdybys tam měl hrušku, tak by název metody getZraleJablko() vůbec nedával smysl.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
BDS+2
Věrný člen
16. 2. 2016   #12
-
0
-

#11 Kit
Máš pravdu, ono evidovat zralost jablek je.. Ale předpokládám, že to zde tazatel uvedl pouze jako příklad. Možná by se to hodilo spíše na zralost sýrů.

Nahlásit jako SPAM
IP: 185.69.69.–
Visual Studio C/C#/C++
(pouze samouk)
Kit+11
Guru
16. 2. 2016   #13
-
0
-

#12 BDS
Se sýry to vyjde nastejno. Metoda sýr->vezmi() bude úspěšná pouze pokud je ten sýr už zralý.

Samozřejmě pokud by polymorfismus měl sahat od jablka až po sýry, tak rozhraní (např. Jídlo) by obsahovalo metodu vezmi(). Metoda pro utrhnutí jablka by se také musela refaktorovat z původního utrhni() na vezmi(), případně by mohlo být jídlo->sněz() nebo jídlo->dej(komu).

Těch variant je samozřejmě spousta a vždycky je potřebné vybrat tu sémanticky nejvýhodnější.

Nahlásit jako SPAM
IP: 194.228.13.–
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
Anonym
~ Anonymní uživatel
429 příspěvků
16. 2. 2016   #14
-
0
-

Děkuji za objasnění, tuším, kam tím míříte. Problém, který ale mám je spíše čistě o OOP, resp. OOP v C++. Architektura aplikace je už nějakým způsobem navržena a já jediné, co chci, je vypropagovat proměnnou z jedné třídy do druhé tak, abych nemusel používat procedurální extern.

Budu tedy konkrétní - mám třídy Zpracuj() a Eviduj(). Cílem je, abych mohl proměnnou ze třídy Zpracuj() předat do třídy Eviduj(). Mám (nefunkční) řešení, které vypadá takto:

Zpracuj.h

#ifndef ZPRACUJ_H
#define ZPRACUJ_H

class Zpracuj
{    
    
public:
    static Zpracuj *inst;

public:
    Zpracuj();
    virtual ~Zpracuj();

    bool getStavNeceho() 
   {
	return stavNeceho;
   }
   static Zpracuj *getInstance() 
   {
	if(!inst) inst = new Zpracuj(); 
	return inst;
   }
   
   static void provedNastaveni();

public:
    bool stavNeceho;

private:
    void setStavNeceho(bool stavNeceho_) {stavNeceho = stavNeceho_;}
    
};

#endif // ZPRACUJ_H


Zpracuj.cpp

#include "Zpracuj.h"

Zpracuj::Zpracuj()
{
	// Chci aby kdyz se nezavola setter, byla default hodnota true
	stavNeceho = true;
}

Zpracuj::~Zpracuj()
{
}

// zavolano napr. z mainu (za urcitych podminek)
void Zpracuj::provedNastaveni()
{
	Zpracuj z;
	z.setStavNeceho(false);
}

Eviduj.h

#ifndef EVIDUJ_H
#define EVIDUJ_H

#include "Zpracuj.h"

class Eviduj
{
    public:
        Eviduj();
  
    private:
        static Zpracuj *instanceZpracuj;
};

#endif // EVIDUJ_H


Eviduj.cpp

Zpracuj* Eviduj::instanceZpracuj = NULL;

Eviduj::Eviduj()
{
 }
 
 Eviduj::metodaKdeChciZjistitHodnotuPromenne()
 {
	 // pri debugovani to zde selze
	 bool stavNecehoZeTridyZpracuj = Eviduj::instanceZpracuj->getStavNeceho();
 }
Nahlásit jako SPAM
IP: 212.79.110.–
BDS+2
Věrný člen
16. 2. 2016   #15
-
0
-

#13 Kit
No právě.. jsou varianty, pro které může být vhodnější to, nebo to. Určitě bych žádnou nezavrhoval.

Nahlásit jako SPAM
IP: 185.69.69.–
Visual Studio C/C#/C++
(pouze samouk)
BDS+2
Věrný člen
16. 2. 2016   #16
-
0
-

#14 Anonym
Já bohužel pořád (doufej, že jsem jediný) nechápu čemu vlastně nerozumíš a co přesně potřebuješ. Skoro jsem chápal co chceš v tvém 2. příspěvku, ale větou "Třída B pak na základě této proměnné provede nějakou akci." jsi to zabil.

Selže, nejspíš proto, že něco k čemu přistupuješ je null.

Nahlásit jako SPAM
IP: 185.69.69.–
Visual Studio C/C#/C++
(pouze samouk)
Anonym
~ Anonymní uživatel
429 příspěvků
16. 2. 2016   #17
-
0
-
Nahlásit jako SPAM
IP: 212.79.110.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 196 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý