Kontrola inicializace objektu – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Kontrola inicializace objektu – C / C++ – Fórum – Programujte.comKontrola inicializace objektu – C / C++ – Fórum – Programujte.com

 

marpit0
Stálý člen
14. 12. 2012   #1
-
0
-

Zdravím, založil jsem si třídu reprezentující nový datový typ (třída obsahuje přetížené operátory a několik privátních členských proměnných). Přístup k jednotlivým členským proměnným je řešen přes set / get metody. Konstruktor je implicitní.

Jde mi o to, že když si vytvořím objekt této třídy, tak jak můžu ověřit, že všechny proměnné byly inicializovány. Napadlo mě založit nějakou privátní proměnnou typu bool, která by byla v konstruktoru inicializována na false a poté by nabyla hodnoty true až v případě zavolání set metod. Nevím, jestli je to nejlepší řešení, jestli neexistuje něco elegantnějšího.

Případně je potřeba takovou věc řešit, pokud bude při použití v programu zajištěno, že takový stav nenastane? 

Díky za rady, s OOP sice mám nějaké (spíše základní) zkušenosti, ale nikdy mě dříe nenapadlo něco podobného řešit. 

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
crazy
~ Moderátor
+10
Grafoman
14. 12. 2012   #2
-
0
-

#1 marpit
buď je můžeš inicializovat v konstruktoru nebo si ty privátní proměnné udělej jako pointery, v konstruktoru je nastav na NULL a uvidíš jestli byli inicializovány nebo ne...

Nahlásit jako SPAM
IP: 147.32.31.–
All you need is vision and time.
marpit0
Stálý člen
14. 12. 2012   #3
-
0
-

#2 crazy
Takže jestli jsem to pochopil dobře:

členská proměnná je definována jako 

int *cislo;

poté následuje konstruktor

cislo = NULL;

a v set metodě dochází k

void setCislo(int c)
{
	cislo = &c;
}

a při použití proměnné kontroluji  

if (cislo == NULL)
	cout << "neni inicializace" << endl;
Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
crazy
~ Moderátor
+10
Grafoman
14. 12. 2012   #4
-
0
-

#3 marpit
 

void setCislo(int c)
{
	cislo = new int(c);
}
Nahlásit jako SPAM
IP: 147.32.31.–
All you need is vision and time.
14. 12. 2012   #5
-
0
-

Možná se mýlím, ale neměla by ta členská proměnná mít i alokovanou paměť?

hu

Nahlásit jako SPAM
IP: 195.178.67.–
marpit0
Stálý člen
14. 12. 2012   #6
-
0
-

#4 crazy
Pak bude ještě potřeba doplnit v konstruktoru  

delete cislo;

?

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
marpit0
Stálý člen
14. 12. 2012   #7
-
0
-

Mi tohle řešení připadá příliš složité   .

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
vitamin+8
Grafoman
14. 12. 2012   #8
-
0
-

 #7 marpit

class C{
	int i;
public:
	C() = delete;	
	C(int i):i(i){}
};

teraz mas istotu ze je premenna inicializovana :)

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
marpit0
Stálý člen
14. 12. 2012   #9
-
0
-

#8 vitamin
Mohl bych poprosit o nějaký komentář, vypadá to jednoduše, ale skončil jsem pod řádkem s public: 

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
marpit0
Stálý člen
14. 12. 2012   #10
-
0
-

#8 vitamin
Aha, takže tohle odstraní implicitní konstruktor? Nebude problém, kdybych chtěl vytvořit pole objektů?

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
vitamin+8
Grafoman
14. 12. 2012   #11
-
0
-

   

C() = delete;  //toto znamena ze nevygeneruje konstruktor bez parametrov (v skutocnosti by to tam ani nemuselo byt)

C(int i):i(i){}	//toto je to iste ako:

C(int i){
	this->i = i;
}
//alebo:
C(int n){
	i = n;
}

Ak chces vytvorit objekt typu C tak ho musis inicializovat, inak sa ti ho ani nepodari vytvorit. napr takto:

C c1(7), c2(8);

edit:

Pole mozes deklarovat napr takto:

C pole[3] = {1, 2, 3};
//dynamicke napr takto:
vector<C> vc{1, 2, 3};

edit2:

ak by si to chcel bez vector tak zas dako takto:

C* pole = (C*)malloc(sizeof(C)*3);
for(size_t s = 0; s < 3; ++s)new(pole+s) C(s);
Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
marpit0
Stálý člen
14. 12. 2012   #12
-
0
-

#11 vitamin
Pokud vytvořím dynamicky pole klasicky bez použití STL, tedy  

C *arr = new C[1];

ale kompiler to neumožní. 

Jinak tím způsobem zápisu se mi dost rozšířily obzory, jsem se s takovým způsobem ještě nesetkal. 

edit: teď se dívám, že jsi byl rychlejší

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
marpit0
Stálý člen
14. 12. 2012   #13
-
0
-

#11 vitamin
Tak přes ten vektor mi to přijde takové přehlednější. Osobně moc malloc nemusím, preferuji raději C++ new a delete. 

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
vitamin+8
Grafoman
14. 12. 2012   #14
-
0
-

#13 marpit
Je lepsie pouzit vector, lebo inak budes musiet manualne volat destruktory pre kazdy prvok pola  

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
marpit0
Stálý člen
14. 12. 2012   #15
-
0
-

moment, proč by to bylo třeba volat destruktor? On se objekt sám neuvolní na konci programu? 

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
vitamin+8
Grafoman
14. 12. 2012   #16
-
0
-

#15 marpit
Alokacia pamete a volanie destruktoru su 2 rozne veci. Pamet sa samozrejme uvolni, ale destruktor sa v urcitych velmi specifickych pripadoch nemusi volat. Ak budes pouzivat vector tak sa o to nemusis starat.

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
marpit0
Stálý člen
14. 12. 2012   #17
-
0
-

#16 vitamin
Já jsem vždy myslel, že destruktor se deklaruje a volá v případech, jako je například, že ve třídě je dynamické pole apod. Jinak jsem chápal, že se použije implicitní a ten že se volat nemusí. Hle, to jsou věci, co se tu dneska dozvídám  

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
vitamin+8
Grafoman
14. 12. 2012   #18
-
0
-

implicitny a explicitny moze byt konstruktor a to sa tyka uplne niecoho ineho.

V tomto pripade si treba uvedomit nasledovne:

  • Ak dynamicky alokujes 1 objekt cez new, tak ho mozes volat s parametrickym konstruktorom.
  • Ak dynamicky alokujes pole objektov cez new[] tak mozes pouzit len bezparametricky konstruktor.

Aby sa to dalo obist tak pouzies placement new. Od normalne new sa lisi v tom, ze prebera jeden parameter naviac(adresu pamete kde je uz predalokovany objekt). placement new nealokuje pamet, len vola konstruktor, preto sa pre neho ani nevola destruktor. Ak alokujes pole objektov cez new[] tak kompilator vie ze pre kazdy prvok pola ma zavolat destruktor. pomocou placement new mozes kludne volat konstruktor len pre kazdy 2 prvok pola, takze kompilator netusi pre ktore objekty (alebo lepsie pre ktoru cast pamete) ma volat destruktor. Preto to musis urobit manualne napr takto:

C* pole = (C*)malloc(sizeof(C)*3);	//alokujes pole pomoco C-eckovskej funkcie malloc ktora nepozna konstruktory/destruktory

for(size_t s = 0; s < 3; ++s)new(pole+s) C(s);	//zavolas konstruktory pre pamet ktoru si alokoval v predchadzajucom riadku (mozes pouzit parametricke konstruktory)

for(C* p = pole; p < pole+3; ++p)p->~C();	//zavolas destruktory 

free(pole);	//uvolnis pole.

std::vector tieto "nebezpecne" veci pred tebou schovava  

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
marpit0
Stálý člen
14. 12. 2012   #19
-
0
-

#18 vitamin
Vektor je dobrý, že člověk nemusí nic řešit, to naprosto souhlasím. 

Mým cílem je však se naučit programovat a kdybych použil vektor, je tam teoreticky vše již vyřešené. Když použiji klasické pole, budu si muset věci jako přidávání, mazání atd. vyřešit sám. 

Zkusím se probrat, co jsi psal výše, zkusím si k tomu ještě něco dohledat a když tak bych se ještě doptal. Ono psát v C++ po dřívějších zkušenostech z C# je docela zábava. C++ je docela mocný jazyk, tedy mocný v tom, že si člověk musí udělat vše sám   . 

Nahlásit jako SPAM
IP: 78.102.62.–
MarPit
vitamin+8
Grafoman
14. 12. 2012   #20
-
0
-

#19 marpit
V c++ si nemusis urobit vsetko sam, ale c++ ti nebrani v tom aby si si to sam spravyl  . Kludne mozes pouzit std::vector alebo iny kontainer a nemusis vobec vediet ako su implementovane (ale je lepsie mat predstavu ako funguju). 

C++ je velmi rozsiahli jazyk, ale na napisanie dobreho programu nepotrebujes ovladat ani jeho polovicu.

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
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, 128 hostů

Podobná vlákna

Inicializace více polí objektů? — založil KingScorpion

Inicializace konstruktoru — založil pepa

AVR inicializace — založil lolkas

Inicializace formuláře — založil Mirek

Moderátoři diskuze

 

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