Body zdarma Java týden
Využij podzimních slev a získej od nás až 40 % bodů zdarma! Více zde
Pouze tento týden sleva až 80 % na Java e-learning!

Diskuze: Dá se někde najít definice defaultních konstruktorů a destruktorů?

Aktivity (2)
Avatar
xmms
Člen
Avatar
xmms:23. září 15:47

Kde se dá zjistit konkrétní definice konstruktorů a destruktorů, které překladač automaticky vygeneroval?

Zkusil jsem:

class Trida
{
private:
        int baf;
public:
//kde je Trida(){} a ~Trida(){} ?
        void setbaf() { baf + 1; }

};

Chci docílit: Chci vědět, co můj program přesně dělá. V knize píšou, že to vytváří a ruší objekty, ale konkrétní zdroják jsem na to nenašel. Chci vidět všechno, co můj program obsahuje. Třeba by se tam dalo najít vysvětlení, proč programy typu hello world můžou mít i několik megabajtů...

 
Odpovědět 23. září 15:47
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na xmms
Martin Dráb:23. září 16:35

Kde se dá zjistit konkrétní definice konstruktorů a destruktorů, které překladač automaticky vygeneroval?

Nevím, zda-li se dají defaultní konstruktory a destruktory najít ve formě zdrojového kódu. Jelikož C++ snad stále nemá reflexi, myslím si, že budou vždy generované překladačem, protože:

  • defaultní konstruktor zavolá defaultní konstruktor na všechny atributy třídy,
  • defaultní destruktor zavolá defaultní destruktory všech atributů třídy.

Myslím, že je tam ale jedna výjimka, a to případ, kdy třídě vytvoříš vlastní konstruktor. Pak pro ni není generován ten defaultní.

Chci vidět všechno, co můj program obsahuje. Třeba by se tam dalo najít vysvětlení, proč programy typu hello world můžou mít i několik megabajtů...

Podívej se na tvůj program třeba v disassembleru typu IDA Pro (nějaká verze by měla být i zdarma a měla by na toto stačit). Máš-li zapnuté ladící symboly, i v disassembleru uvidíš jména funkcí, globálních proměnných... a dozvíš se, co všechno bylo do binárky zahrnuto (což se třeba odvíjí od toho, zda-li povolíš překladači/linkeru vyházet věci, které se v programu prokazatelně nepoužívají).


Pokud Hello World naprogramuješ jako

std::cout << "Hello World" << std::endl;

nemůžeš se divit, že velikost výsledné binárky může být značná. Zvláště pokud kompiluješ pomocí mingw na Windows, tedy nepoužíváš běhové knihovny od Microsoftu (jelikož v MS znají ten jejich OS, dokážou napsat menší běhové knihovny). std::cout je stream, což je dosti bohatá třída skládající se ze spousty věcí, které pak musí být také zahrnuty do binárky. Dále k tomu můžeš připočítat kód řešící obsluhu výjimek... a postupně se to nabalí.

Nahoru Odpovědět  +1 23. září 16:35
2 + 2 = 5 for extremely large values of 2
Avatar
xmms
Člen
Avatar
Odpovídá na Martin Dráb
xmms:23. září 22:53

Používám Microsoft visual studio a někdy g++ v mingw. Dá se nějak jednoduše nastavit kompilátor, aby tam dával jen funkce, které program potřebuje? Třeba ve visual studiu musím zahrnout runtime library v sekci code generation bez toho DLL, aby program nebyl závislý na nainstalovaných Visual C++ Redistributable, jinak by to házelo chybu, že mu chybí knihovna. Program má kvůli tomu cca o 250 kB navíc.

 
Nahoru Odpovědět 23. září 22:53
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na xmms
Martin Dráb:23. září 23:58

Třeba ve visual studiu musím zahrnout runtime library v sekci code generation bez toho DLL, aby program nebyl závislý na nainstalovaných Visual C++ Redistributable, jinak by to házelo chybu, že mu chybí knihovna. Program má kvůli tomu cca o 250 kB navíc.

Ano, je to tak. Použitím C++ ti program opravdu hezky "nakyne", protože STL je prostě taková mamutí a zřejmě překladači dělá problém vyházet funkce, které se nepoužijí. Vezmi si třeba kus kódu:

if (x)
  a();
else b();

Ty můžeš vědět, že x bude vždy nenulové (a tedy se bude vždy volat a, b se nikdy volat nebude, takže jej nemusíš do binárky vůbec zahrnout), ale pro překladač toto může být velmi velmi netriviální (obvykle nemožné) zjistit. Navíc, pokud se takový kód nachází v šablonované funkci, která je několikrát instanciována, pro každou instanci se takhle zvláště nevyignoruje příslušná instance funkce b.

Pokud chceš menší binárku (a nechce používat nějaký externí packer aka UPX):

  • piš v Céčku, neb to nenabere s sebou tolik balastu,
  • nepoužívej běhovou knihovnu vůbec (/NODEFAULTLIB), ale uznávám, že je dost peklo si naimplementovat potřebné funkce vlastními silami.

Dost funkcí (memset, memmove, memcmp, fopen, fclose, fread, fwrite...) lze poměrně jednoduše implementovat prostřednictvím Windows API (které jsou samy implementovány na každém Windows, takže je nemusíš tahat s sebou). Myslím, že seženeš i snprintf (user32.dll?, ntdll.dll?). Případně si můžeš implementovat jen podmnožinu, kterou potřebuješ.

I třeba taková zdánlivě jednoduchá funkce pro kopírování paměti - memcpy může zabírat pár set bajtů jen protože, obsahuje různé varianty pro kopírování různě velkých bloků dat (za využití SSE a jiných speciálních instrukcí).

Ale bez běhové knihovny se žije dost těžko, to přiznávám. Musíš si sám naparsovat příkazovou řádku, sám se případně postarat o konzoli... a nebo se striktně vyvarovat použití funkcí z téhot knihovny. Překladač je pak vyhází, ale i tak ponechá ty, které jsou součástí inicializace a finalizace.

Nahoru Odpovědět 23. září 23:58
2 + 2 = 5 for extremely large values of 2
Avatar
Patrik Valkovič
Šéfredaktor
Avatar
Patrik Valkovič:24. září 0:04

Řešit kB v době, kdy obrázky mají jednotky MB a filmy mající několik GB streamujeme realtime přes internet, se mi zdá poněkud přehnané. Pokud se nejedná o miktrokontrolery s omezenou pamětí (které by byly spíše programované v C), nevidím důvod takové věci vůbec řešit.
#justsaying

Nahoru Odpovědět  +1 24. září 0:04
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Caster
Člen
Avatar
Caster:4. října 17:53

Pokud jde o rychlost a úsporný kód, udělám si příslušné funkce v x64 assembleru. V C++ jsem si např. alokoval 4 GB RAM, načetl do ní na 2x po 2,5 GB textový soubor a pak v assembleru pracoval s 38 miliony řádků ;-).

 
Nahoru Odpovědět 4. října 17:53
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na Caster
Martin Dráb:4. října 20:33

a pak v assembleru pracoval s 38 miliony řádků ;-).

To není problém ani bez použití Assembleru. Jenom je potřeba vyhnout se C++kovým streamům, protože výkon jaksi asi nebyl jedním z cílů při jejich návrhu...

Nahoru Odpovědět 4. října 20:33
2 + 2 = 5 for extremely large values of 2
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Caster
DarkCoder:4. října 20:55

Moc dobře si pomatuji o jakou aplikaci se jedná. Společně jsme tu řešili drobné neance a nepochybuji o funkčnosti aplikace. Přesto bych se zaměřil na optimalizaci datových souborů, ze kterých souřadnice o průběhu letu taháš. A to by bylo aby se rychlost vykreslení trasy drasticky nesnížila, stejně tak jako paměťové nároky... :-)

Nahoru Odpovědět 4. října 20:55
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Caster
Člen
Avatar
Odpovídá na DarkCoder
Caster:5. října 1:48

Začátky byly těžké, ale s pomocí zdejších expertů jsem to dal dohromady, díky, pomoc a rady velmi oceňuji :-).

 
Nahoru Odpovědět 5. října 1:48
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.