Olyan programot keresek, mint Delphi. Rakok mondjuk egy Edit mezőt vagy gombot a formra, majd duplán rákattintok és már írhatom is hozzá a kódot. Meg állíthatom a mező tulajdonságát vagy nagyon jó kódolási példát látok rá. Aztán fordítom és lám működik a program rendesen.
Ehhez szeretnék közelíteni, ezt Delphinél nagyon szépen megoldották.
Ja és ezt lehetne überelni azzal, hogy ingyenes. Azt már nem mondom, hogy néhány gombnyomással akár több rendszerre is lefordítja a programot, bár ez sok C++ programozó álma. :)
Tapasztalataim Linux alatt:
Kdevelop:
LXDM felületű Manjaro linux alatt fel se megy. Lehet, hogy az általa gyártót programjai sem, ami azok számára is gond, akik nem használnak KDE felületet.
QT5:
Jónak tűnik, csak nem értem a működését. Az assistant, a designer, Creator és jó néhány cucca egymástól külön van, külön kell elindítani. Delphinél még tudtam, hogy mi hogyan működik, minden teljesen logikusan volt felépítve. Hogy fogok én itt egy rendes programot csinálni? Talán egy videó vagy képes tutorial lenne a jó egy kis program felépítéséről a nulláról a futtásáig, kész program legyártásáig. Nyitott vagyok rá, mert vannak itt komponens paletták és leírni sem szeretném a QT-ét.
Glade:
Hasonlóan a QT5-höz itt is voltak komponensek paletája, de se programozni, se futtatni nem tudtam.
Monodevelop. Itt már volt form, volt kód írási lehetőség. Ha viszont egy szűz projektet akartam futtatni, amibe már belegenerált jó pár dolgot, akkor hibákat írt ki.
Anjuta, CodeBlocks, Edyuk,TheIDE. Ezekkel sem nagyon boldogultam.
Windowsos tapasztalataim még nincsen, ott csak konzolost írtam.
Biztosan mindegyikhez megvan a trükkje, hogy mindegyik jól működjön, csak ne okoznának ennyi fejfájást. Bezzeg egy sima GCC fordítóval remekül boldogultam Terminálban. Csak én grafikus programot akarok készíteni, nem pedig konzolost.
A ti tapasztalataitokra lennék kíváncsi és egy szinte teljesen kezdőnek melyik programot ajánljátok. Melyiket egyszerűbb használni, melyikhez van jól használható segítség? És melyikkel szív kevesebbet az ember.
Rólam csak annyit, hogy régen Delphiztem, most nagyban tanulom a C-ét, később a C++-t. Most a konzolos programok írásakor jöttem rá, hogy ha azt is akarom, hogy mások használják a programom, akkor grafikus felületre kell nekik megírnom.
- 19181 megtekintés
Hozzászólások
Az assistant, a designer, Creator és jó néhány cucca egymástól külön van, külön kell elindítani.
Ez így nem igaz, a Qt Creatorban van beépített Designer. A Qt dokumentációja nagyon jó, itt egy példa, amelyben egy szövegszerkesztőt lehet írni Qt Quickkel, itt ugyanaz Qt Widgets alapokon. Minden másra ott a Mastercard, izé, az online és offline (a Qt Creatoron belül) elérhető dokumentáció, példák, tutorialok.
Csak indítsd el a Qt Creatort, és a kezdőképernyőn ott van jobb oldalt az Examples és a Tutorials fül.
- A hozzászóláshoz be kell jelentkezni
+1
Qt-Creator egész jó IDE, és maga a Qt szerintem az egyik legjobb cross-platform framework (nem csak GUI szinten). Mondjuk ha C++-os megoldás akkor inkább a Qt-4 mint a Qt-5.
- A hozzászóláshoz be kell jelentkezni
Nekem nem tűnt fel, hogy a qt5-öt átírták volna C++-ról más nyelvre, de lehet csak én nem figyeltem...
Szóval ha lehet ne propagáljunk már egy kezdőnek egy olyan verziót ami elavul mire megtanulja (még akkor is, ha a váltás nem különösebben problémás).
Vagy te is csak a "a QML kinyírta a Widget-eket" FUD-ot terjeszted?
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Nem írták át, de a Qt5 filozófiája azért kezd egy kicsit eltávolodni attól, amit a Qt a kezdetektől magában foglalt (én a Qt-t a 2.3 óta használgatom/használom). Szerintem (én legalább is úgy érzem), hogy most már nem annyira a C++-os vonal az amit preferálnak, inkább nyitnak más nyelvek/megoldások felé (amivel lehet használni a framework-öt).
- A hozzászóláshoz be kell jelentkezni
A Qt5 tényleg nagyon más világ, kellett egy kis idő míg hozzászoktam. Ennek ellenére azt mondom megérte megismerkednem vele. Viszont a C++ nekem még mindig problémás, eltart egy ideig míg megbarátkozok vele.
- A hozzászóláshoz be kell jelentkezni
Tényleg a Creator lesz a jó megoldás. Ugye van az Example rész, ahol beírtam volna a "Clock"-ot, ahogy példaként ajánlja. A mező mellett viszont nincs az a kiválasztható QT5 akármi és az Enter leütése hatására sem történik semmi. Tehát valamit még hiányol. Ez van linux alatt. Majd megnézem windows alatt is.
Ha jól látom, tudok majd Android platformra is programot írni. Ha ezt C++-szal ötvözve neg lehetne tenni, az nagyon jó lenne. Ugyanis Linux, Windows, Android az, amire szívesen írnék.
- A hozzászóláshoz be kell jelentkezni
+1 A QtCreatorra. A többi cuccal meg sokáig nem kell foglalkoznod.
(Régen a creator előtti időben volt jelentőségük. Manapság már csak akkor kerülnek elő, ha programozók és nem programozók közössen dolgoznak egy nagyobb projekten. Pl.: a gui megszerkesztésének kiadása ui tervező grafikus kollégának, stb...)
Zavard össze a világot: mosolyogj hétfőn.
- A hozzászóláshoz be kell jelentkezni
"Olyan programot keresek, mint Delphi."
Lazarus? Persze nem C++, hanem Pascal, mert olyan, mint a Delphi.
A többi, amiket írtál egyébként mind használható, csak el kell olvasni valami bevezetőt róluk. Meg persze nem olyanok, mint a Delphi.
- A hozzászóláshoz be kell jelentkezni
Van még az Ultimate++, de az is saját állatfaj, amivel természetesen foglalkozni kell (mint a többivel) - ha akarsz valami komolyabbat vele.
- A hozzászóláshoz be kell jelentkezni
Szerintem Qt. A QtCreator kell neked, a többi standalone cucc korábbi, Creator mentes fejlesztésre lett kitalálva, nagy részük már integrálva van. Talán a Linguist az egyetlen kivétel, de az csak i18n-hez kell.
Kdevelop csak egy IDE, lehet benne sima C, C++, illetve Qt-s és KDE-s projektet is csinálni.
Tudom, hogy nagy élvezet olyan Linux disztribúciót használni aminek egyjegyű a felhasználói tábora, de ha már egy KDevelop telepítése is gondot okoz neki (vagy rajta neked) akkor nem biztos, hogy a legjobb környezet kezdőként a fejlesztéshez.
Elég hibát raksz majd bele a programjaidba magad, ne kelljen még a környezet hibáival és nem szabványos megoldásaival is szopni...
A Qt weboldala tökig van tutorial-lal, pl ez jó lehet kezdésnek: http://qt-project.org/doc/qt-5.0/qtdoc/gettingstartedqt.html
Itt találsz még egy párat: http://qt-project.org/doc/qt-5.0/qtdoc/qtexamplesandtutorials.html
Én mondjuk azt javasolnám, hogy kezdj Widget alapú GUI val, azaz ha olyat látsz, hogy QtQuick vagy QML, azt hagyd későbbre.
Mondjuk mielőtt Qt-zni kezdesz jó volna érteni a C++ alapjait, különös tekintettel az objektum orientált programozás alapjaira (kostruktor-destruktor, öröklődés, virtual fv-ek), memóriakezelés stb.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
A Qt5-öt viszont már C++11 ismerettel érdemes használni, úgy az igazi :-)
- A hozzászóláshoz be kell jelentkezni
"objektum orientált programozás alapjaira (kostruktor-destruktor, öröklődés, virtual fv-ek),"
Ezzel picit vitatkoznék: ennyitől csak OOP eszközök felhasználásával készített program lesz a végeredmény, ami messze van az objektum orientált programozástól.
Ha gányolás, akkor Qt + Python variációt javasolnám első próbálkozásra, mert gyorsabban lehet kisebb, de már működő, használható alkalmazásokat írni vele. Igaz, így a Qt5 jó eséllyel kiesik.
Ha meg programozás, akkor előbb célszerű pár hónapot áldozni az OOP elméleti alapjaira (ami messze több annál, hogy az OOP kulcsszavakat használod a programban) és csak utána belevágni az egészbe (lásd Robert C. Martin könyvei!)
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Az OOP melletti felsorolás arra vonatkozott, hogy ezen fogalmak ismerete nélkül el se kezdjen a Qt-val foglalkozni, mert fogalma nem lesz, hogy mi történik a kódban...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
Párhuzamosan tanulom a kettőt. Tehát amit tudok C vagy C++ nyelven, azt már QT-hez is tudom használni. Hogy mit tudok kihozni, az függ attól, hogy mit tudok C/C++ nyelven megvalósítani a pillanatnyi tudásom alapján és mennyire tudom a QT-ét használni.
Elméletileg sokmindennel tisztábban vagyok az osztályokkal, objektumokkal kapcsolatban. Ez a tudás ha jól gondolom nem kell még egy űrlaphoz, amiben számokat kérek be és matematikai műveleteket végeztetek el, switch, do-whilr, for ciklusokkal oldok meg ezt azt. És tudod már az is jó, ha nem konzolosan működik, hanem egy gombra való kattintással hozza elő az őt érdeklő dolgot. Persze lehet checkbox, radio button vagy más módon is, grafikusan jó pár dolgot meg lehet oldani.
- A hozzászóláshoz be kell jelentkezni
Kérlek, Qt-t írj QT helyett. Nem ugyanaz.
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
Hi!
Windows alatt kezdőknek a C# + winforms, de tudsz használni managed c++-t is. (lényegében c++, kicsit kiterjesztve, hogy tudj garbage kollektált objektumokat is használni)
Keresztplatformos c++ programozáshoz Qt, vagy urambocsá' java/swing vagy java/swt.
(elsőre nem szembetűnő, de sokat lehet szívni qt-vel is: ha régi a distro ahol futnia kell az appnak, lehet, hogy régi a libc, nincsenek fent libqt**-dependenciák, stb. Java-hoz az alkalmazás mellé másolod a jre-t és kész vagy...)
- A hozzászóláshoz be kell jelentkezni
Az ugye megvan, hogy C++ volt a kérdés, erre jöttök itt C# meg Python emlegetésével.
Arról ne is beszéljünk, hogy a Managed C++ kihalt 2005-ben, a helyébe lépő C++/CLI kb tavaly, a jelenlegi csoda meg C++/CX névre hallgat és úgy saccolom, hogy 2017-ben dobja az MS.
A szép bennük az, hogy hasonló szintaxis mellett (pl ^ pointer) tökéletesen másképp működnek...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
A kérdezőnek (ha jól értem), kizárólag Delphi tapasztalata van. Ilyen előélettel nekiesni a C++-nak csak azért, hogy Qt-s programokat írjon, felér egy öntökönbökéssel.
Jó, nem vagyok etalon, de némi C-s előélettel ugrottam neki a C++-nak, aztán sírva menekültem előle. :)))
Pythonból, PyQt-t vagy PySide-t használva könnyen ki lehet próbálni, hogy mi, mire való, hogy működik és maga a python tud annyira primitív lenni, hogy elsősorban a Qt-re tudjon koncentrálni, ne a nyelv (esetünkben a C++) rigolyáira. Ha ott valamennyire megismerte, el tudja dönteni, hogy akarja-e egyáltalán a Qt-t vagy dobja az egész témát. És a pythonos Qt, meg a C++-os eléggé hasonlóak, ahogy a doksit elnéztem amikor ezzel szórakoztam.
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Tanítottak nekem C++-t, csak lusta voltam, mint a dög. Most alapoktól rengeteg idő ráfordítással tisztességesen megtanulom ezt a gyönyörűen szép nyelvet. :)
Nem azért tanulom a C++ nyelvet, hogy a QT-ét használjam, habár ez se lehet rossz motiváció. Inkább olyan fejlesztői programra van szükségem, ami a C++ nyelvet alkalmazva tudok jó grafikus programot készíteni lehetőleg minél több népszerű operációs rendszerre. És lehet, hogy a QT tényleg alkalmas lesz erre.
Python nyelvet nem akarom csak azért megtanulni, hogy kiismerjem a QT-ét. Plusz időbe telne és egy újabb programozási nyelvvel lenne terhelve az agyam. C++, PHP, esetleg linux bash programozás elég lesz nekem.
Egyébként ahogy elkezdem majd a QT programot használni, úgy fogom jobban megismerni, Szerintem nem kell évekig használnom, hogy rájöjjek, hogy mégsem jó nekem. Ha valóban nem nekem való.
- A hozzászóláshoz be kell jelentkezni
Szerintem a kettő egyszerre sok. Előbb tanuld meg a C++-t rendesen, és ha már elég jól megy, csak akkor kezdd a Qt-t. Már csak azért is, mert a Qt-nak vannak olyan megoldásai, amik "kiterjesztik" a C++-t, lásd pl. signals & slots.
- A hozzászóláshoz be kell jelentkezni
"Szerintem a kettő egyszerre sok."
Szerintem ez hülyeség. Gyakorlat közben lehet normálisan tanulni. Én inkább azt javasolnám, hogy nézzen meg más környezeteket is mellé, hogy ne csak egyet lásson. Ultimate++ például ideális lehet, bár ott Android target nincs egyelőre. Viszont Ultimate++-ban a Qt signal-slot mechanizmusa helyett lényegesen elegánsabb, natív C++ megvalósítás van. És rengeteg más egyéb komolyan szemet gyönyörködtetően elegáns kódot is találhat benne :)
- A hozzászóláshoz be kell jelentkezni
Azért arra a THISBACK makróra nem lennék olyan büszke. :)
boostban van szebb megoldás is.
Egyébként Qt5 óta van fordítás időben ellenőrzött signal-slot, még lambda fv-ekkel is megy.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
THISBACK ízlés kérdése. Nekem tetszik :)
Sokan valamiért ördögtől valónak tartják a makrókat, pedig néhány esetben nagyon hasznosak tudnak lenni. THISBACK makrók például olvashatóbbá teszik a kódot és csökkentik a gépelésigényt.
Qt5-öt még nem próbáltam, de ez jó hír :)
- A hozzászóláshoz be kell jelentkezni
Pont azert javaslom inkabb a python-t.
A C++ megtanulasa extrem nehez. Mindenki csak ganyol benne evekig.
python kb 10x effektivebb es konnyebb. Meg persze lassabb is.
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
Akkor felrakja. Őszintén megmondom, hogy egyáltalán nem bízok a java-s dolgokban, bármennyire is divat lett használni és erőltetik. Hajlamosak a java-s cuccok igen szépen zabálni az erőforrásokat.
A C# nem valami Windowsra specializálódott programozási nyelv? Minek tanuljam meg még azt is külön, ha C++ nyelven több rendszerre is tudok írni? Arról nem is beszélve, hogy a C#-sal írt programokat csak Windows rendszerekre lehet használni.
A C++ nyelv sem tökéletes, ott is sokmindenre kell figyelni. Mégis nagyobb fantáziát látok benne, mint bármelyik más nyelvben.
- A hozzászóláshoz be kell jelentkezni
A C# csak egy nyelv, önmagában a windowshoz semmi köze. A .Net-hez, amihez a C#-ot tervezték, elérhetőek alternatívák, pl. a Mono, amik segítségével futtathatsz .Net programokat más platformokon (feltéve hogy a program csak olyan assemblyket használ, amiket a Mono tud).
- A hozzászóláshoz be kell jelentkezni
Értelmes C# projektet csak Windows felett lehet csinálni. Ergó nem multiplatform a felhasználása.
- A hozzászóláshoz be kell jelentkezni
Unity3D? Banshee? Hadd ne soroljam, van ellenpélda bőven.
- A hozzászóláshoz be kell jelentkezni
Koszonjuk, majd ertesitjuk.
Kezdjuk mondjuk itt:
http://www.mono-project.com/Screenshots
A C++ multiplatformsagarol meg annyit, hogy #ifdef WIN32. Vagy hogy kicsit meg kellemetlenebb legyek:
http://wiki.apache.org/stdcxx/C%2B%2B0xCompilerSupport
http://cpprocks.com/c11-compiler-support-shootout-visual-studio-gcc-cla…
Have fun. Windows-on meg csak-csak odahanyod a redist-et a telepitobe, de Linuxon meg ennyi sincs. Megirod a kodot, aztan remeled, hogy minden user minden OS-enek minden compiler-enek minden verzioja meg fogja valahogy enni (nyilvan nem igy lesz). Micsoda hordozhato kod lesz ebbol, kerem szepen!
Plusz en nem lattam meg olyan kodot, ami csakis es kizarolag a standard konyvtarakat hasznalta volna. Bar a fenti linkek mar ravilagitottak, hogy meg akkor se garantalna az egvilagon semmi a fordulast se, nemhogy a futast.
A Java is fut minden rendszeren... amire van JVM. .Net ugyanez. Python detto. Sorolhatnam.
Nincs olyan, hogy valamit megirok, es akkor az egycsapasra megy mindenhol. A multiplatform kisebb vagy nagyobb mertekben, de mindig szopas es pluszmunka. Aki szerint a nativ kod hordozhatobb, mint a menedzselt, az vagy sosem csinalt meg ilyet, vagy egyszeruen hulye.
- A hozzászóláshoz be kell jelentkezni
Az erőforrászabáló java programok pont olyanok, mint az erőforrászabáló c++ programok :)
Egyébként megint nyelv flamewar lesz belőle. Én azt javasolnám, hogy ha valaki OOP-t akar tanulni, akkor először java-val kezdje, aztán
ha érti, hogy minek csinálunk interface-t, amikor osztályt is lehet, vagy mikor melyik design pattern-t érdemes használni, és mikor nem,
stb. magyarul már tud absztrakt módon gondolkodni, na, akkor szabad c++-hoz nyúlni.
- A hozzászóláshoz be kell jelentkezni
Szerintem ez egy nagyon rossz tanács. Először is, teljesen más a két ökoszisztéma (fejlesztői eszközök, könyvtárak, ...). A Java -> C++ váltás egy elég komoly sokk lesz valakinek, aki csak az egyikben mozgott. Miért akarod ezzel (is) szívatni az embert? A C++-t is lehet egyszerűbb módon használni a kezdetekben, itt aztán tényleg nem mindegy, hogy milyen anyagból tanul az ember. A buktatókkal így is úgy is meg kell küzdeni előbb-utóbb. Mintha Jávában nem lehetne épp elég hülyeséget csinálni, meg megszokni. Nem garancia az sem a jó osztályhierarchiára meg design pattern használatra. Az valahol ott kell kezdeni, hogy computer science.
- A hozzászóláshoz be kell jelentkezni
Ezért mondom, hogy ha valaki ilyesmire adja a fejét és komolyan gondolja, szánjon rá pár hetet/hónapot az OOP alapokra, lehetőleg nyelvfüggetlenül. Pythont azért mertem javasolni első körben, mert ahogy valami okos ember írta, nagyon emlékeztet egy pszeudo kódra az egész. Nem kell benne törődni olyan finomságokkal, mint memóriakezelés és hasonlók, amik C jellegű nyelvekben azért elég jellemzőek emlékeim szerint, nem kell küzdeni a fordító programmal stb.
Említhettem volna pl. ruby-t is, de úgy tudom, arra nem készült valóban használható Qt implementáció.
Persze lehet úgy is, hogy kitalálom, hogy C++ és Qt, majd tutorialok alapján összetákolok valamit és örülök, hogy működik, de annak a végeredménye szinte mindig a gányolás.
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Nekem ugye célom, hogy egy program minél kevésbé zabálja az erőforrásokat és hibamentesen fusson. Ebbe beletartozik például a pointerek jól használata, meg például nem hagyunk szemetet a memóriában, amire már nincs szükségünk. Vagy egymásba épülő feltétel ciklussal se végeztettünk el műveleteket fölöslegesen.
Mondjuk amikor az ember profibb lesz és ránéz a régebbi program forráskódjára, akkor már rengeteget tud optimizálni rajta. Akkor van a gond, ha már sokkal előrébb kiadott programot a saját kezéből az ember másnak és problémákat okozott. Ha viszont rendesen futott, akkor az nem járt negatív következményekkel és lehet még utólag optimizálni rajta. Ha nemcsak magunknak csináljuk a programot és ez sokaknál így van, akkor már felelősséggel is van.
- A hozzászóláshoz be kell jelentkezni
Nekem ugye célom, hogy egy program minél kevésbé zabálja az erőforrásokat és hibamentesen fusson. Ebbe beletartozik például a pointerek jól használata, meg például nem hagyunk szemetet a memóriában, amire már nincs szükségünk.
Ez nagyon szép és jó, de mire ilyen szinten megtanulod a C++-t, addigra évek telnek majd el, és kínkeserves szopásokkal lesz tele az út. Persze csak akkor, ha a C tudásánál többet is akarsz belőle használni. Ha nem kellenek az exception-ök, nem kellenek a template-ek (ergó az egész STL-t is elbukod, sőt, szinte minden C++-specifikus könyvtárat, tehát csinálhatsz mindent magadnak, kézzel), akkor gyorsan fog menni a dolog.
- A hozzászóláshoz be kell jelentkezni
Szerintem embere válogatja, hogy mit idéz elő nála a C++.
Konkrétan én is Delphi irányból kötöttem ki a C++-nál, de számomra inkább "kinyílt a világ" azzal, hogy a C++-t megismertem.
Őszintén szólva ezekkel a "kínkeserves szopásokkal" nem találkoztam és a többi C++ programozó sem, akiket ismerek, pedig elég nagy projecteken dolgoztunk mindannyian. Ehelyett inkább kifejezetten élvezetesnek találjuk a munkát a C++-szal, ami közvetlenül eredményezi a magas produktivitást és az építő, kreatív hozzáállást is.
- A hozzászóláshoz be kell jelentkezni
És mennyivel jobb, ha neked ezekre nem kell figyelni, hanem a nyelv megakadályozza, hogy ne tudjál ilyen hibákat elkövetni. A másik, hogy kódot csak
a legvégső esetben reszelünk adott processzorra, ehelyett megfelelő algoritmusokat használunk, lásd még algoritmuselmélet c. könyv. Aztán van ilyen,
hogy unit tesztelés, meg integrációs teszt, vannak már gui tesztelő könyvtárak is, ezekkel biztosítjuk, hogy amit szeretnénk, és amit a programunk végez,
azok között legalább korreláció legyen :)
- A hozzászóláshoz be kell jelentkezni
Akinek a programnyelv korlátai kellenek, hogy megvédjék a saját figyelmetlenségétől vagy hülyeségétől, annak nem szabad megengedni, hogy egy komolyabb projecten dolgozzon.
C++ rendkívüli előnye szerintem, hogy a programozó alkalmatlansága nagyon hamar kiderül. Egy dilettáns akkor is zavaros kódot fog írni, ha helyette kezeli a rendszer a memóriát.
- A hozzászóláshoz be kell jelentkezni
Tudnál ilyen korlátra konkrét példát? (korlátra, nem segédeszközre, amilyen mondjuk egy garbage collector!)
Szerintem a nagy projekteknél mindig szem előtt kell tartani az ú.n. emberi tényezőt. Bárki, bármikor tévedhet. Ha olyan környezetben dolgozol, ami ezt segít kivédeni, akkor esélyes, hogy kevesebb hibát produkálsz a végén.
Nem?
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Javában elég idegesítő korlát pl. az automatikus memóriamanagement hiánya.
C++-ban megszokott gyakorlat pl. az erőforrás lockolásokat úgy megoldani, hogy egy scope-ban létrehozunk egy lokális példányt a lockból, ami automatikusan felszabadul, mikor a scope-ot elhagyjuk.
Egy másik, hogy én személy szerint a GC-t leginkább értelmetlen korlátozásnak tartom, ami egy teljesen rossz C++-programozói szokásra született workaround. A GC-t a rossz szokással együtt a Java nyelv részévé tették. C++-ban persze ma már egyre kevesebben programoznak ilyen módon, leginkább csak azok, akik Java irányból jönnek.
Arról van szó, hogy sokan teljesen indokolatlanul mindent new operátorokkal hoznak létre normál tartalmazás és containerek használata helyett. Ez hozza be az elfelejtett delete operátorok problémáját, amire workaroundként megszületett a GC.
Ha viszont betartod egy projectben a "minden tartozik valahova" elvet, nem használsz new és delete operátorokat és a malloc/free párost sem, akkor az egész probléma köddé válik. Egészen nagy projecteket láttam, amikben nem volt egy new operátor sem, vagy maximum 1-2.
És mégsem lennék annak a pártján sem, hogy akkor tiltsuk be a new operátort. Néha mégis szükség van rá, pl. a containerek kódjában mindenképpen.
- A hozzászóláshoz be kell jelentkezni
+1 :)
- A hozzászóláshoz be kell jelentkezni
Mit értesz automatikus memóriamenedzsment hiánya alatt? Java-ban pl. így működik:
public class X{
}
public void test(){
X x = new X();
}
test() hívásával létrejön egy objektum, de a kilépés során automatikusan megszűnik, mivel nincs rá referencia (aztán majd a gc egy idő után kitakarítja.)
- A hozzászóláshoz be kell jelentkezni
Szerintem a RAII-re gondol.
Megoldhato hasonlo java-ban is finalize-zal kb. Illetvel, a 7-es mintha bevezetett volna egy hasonlo doglot, de a nevere mar nem emlekszem.
"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series
- A hozzászóláshoz be kell jelentkezni
Oké, elolvastam... erre két megoldás van (a finalize a destruktor nagyon nem megfelelője)
try{..}finally{..} a standard megoldás, illetve 1.7-től elvileg:
try (resource_to_be_cleared){}
ahol a resource_to_be_cleared-nek meg kell valósítania az AutoCloseable interfészt.
- A hozzászóláshoz be kell jelentkezni
Latszik, hogy reg javaztam. Finally-ra gondoltam, csak sikerult elirni.
"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series
- A hozzászóláshoz be kell jelentkezni
try-with-resources
Mondjuk ha androidra fejlesztesz, akkor szopacs.
Illetve ha több mint egy resource-od van, akkor elég randa lehet a sok egymásba ágyazott block...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Igen, erre gondol a kollega, konstruktor lefoglalja az erőforrást, destruktor felszabadítja.
Modern C++-ban unique_ptr és shared_ptr a bevett, nem a new-delete, erre gondolt. Illetve a konténerek, ahol lehetséges, de ezt említette is.
Viszont ez nem oldja meg cirkuláris referenciák kérdését. A shared_ptr nem kezdőknek való téma, nem lehet beültetni az egységsugarú indiai kódolót, ha megfelelő minőségű kódot szeretnénk.
Többek közt ezért is javaslom, hogy C++-ba csak az kezdjen, aki eltökélt, hogy igen, ő C++ szakember akar lenni. Akit nem érdekel a natív, teljesítményorientált programozás, az toljon python-, C#-ot vagy valami más modern nyelvet. Persze a C++11 már nagyon cool, de évek kellenek mire valaki mélyen megérti, miért is jó egy egy feature.
- A hozzászóláshoz be kell jelentkezni
Én úgy fogalmaznám, hogy csak az tudja leginkább kihasználni a C/C++ nyelvben lévő lehetőségeket, aki eleget foglalkozik vele, minden egyes fortélyát megtanulja. Szerintem egy kezdőnek még nem szükséges a konstruktorokkal és destruktorokkal foglalkoznia. Majd amikor komolyabb programot csinál és elég éretté válik a megértéséhez, tanulásához, alkalmazásához és képes előnyére fordítani, akkor lesz neki igazán jó. Szerintem senki sem úgy kezdi, hogy osztályokat csinál. Igaz lehet, hogy hamarabb lesz szüksége ilyesmikre, mint ahogy azt az ember gondolná.
Tényleg nem olyan a C nyelv, mint a html programozás. Van akinek még ez utóbbi sem megy, nemhogy valamilyen komolyabb nyelv. A C/C++ valóban az egyik legnehezebb nyelv. Tudom, hiszen régen én is gondban voltam vele. Azóta én is változtam és a vele kapcsolatban szerzett eddigi tapasztalataim és ismereteim alapján már boldogulni fogok vele. Igaz nem lesz gördülékeny minden. Az élet sem az, szokták ezt mondani.
- A hozzászóláshoz be kell jelentkezni
A C egy viszonylag primitív nyelv, szerintem nem lehet összehasonlítani a C++ képességeivel.
Használni macerás, de maga a nyelv elég egyszerű.
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Nem, semmilyen *_ptr és semmilyen pointerezés nem kell. Ha mégis, azt elfedjük valamivel, elrejtjük valami osztályba, ami nem használható veszélyesen. És csak abból használunk példányokat kizárólag sima memberként vagy esetleg containerekben.
A lényeg, hogy az egész projectben ne legyen semmilyen manuálisan kezelt dinamikus memóriakezelés sehol se, azaz minden objektum tartozzon valahova.
Sajnos a factory és hasonló patterneken edződött programozóknak ezt nehéz még elképzelni is. A tapasztalatom, hogy ez szinte kizárólag a Java képzést nem nagyon kapott kezdőknek és a régi motoros C++-osoknak megy akik világ életükben beágyazott környezetbe írtak programokat, ahol alapkövetelmény az akár évtizedeken keresztüli hibátlan működés.
- A hozzászóláshoz be kell jelentkezni
tudnál erre valami példát mutatni? Pl. ha egy metódusból visszaadsz egy objektumot,
akkor az hogy néz ki?
- A hozzászóláshoz be kell jelentkezni
Az ilyen design kerülendő. Talán említettem is fentebb. Visszatérési értékként jellemzően egyszerű visszatérési értékeket adunk vissza, esetleg nagyon pici objektumot a nagy copy konstruktorok futását elkerülendő.
Egy tipikus függvényhívás a "nem const" referenciaként átadott objektumokat állítgatja.
Egyébként is elvárás a normális visszatérési értékek használata, mivel exception-kezelés a struktúrálatlansága miatt nagyrészt kerülendő az ilyen projectekben, vagy esetleg csak helyileg alkalmazható pl. egy parser egyszerűsítésére.
- A hozzászóláshoz be kell jelentkezni
Ah, tehát ha valami visszatérési értéket akarsz, akkor átadsz neki paraméterben egy
objektumot, hogy azt állítgassa? Vagy nem jól értem?
Az exception kezeléssel mi a gond? Azt tudom, hogy C++-ban valahogy máshogy van, mint
a java-ban...
- A hozzászóláshoz be kell jelentkezni
Igen, jól érted.
Exception-ökkel ott van a probléma, hogy az osztály interfészében nem látszik. Teljesen áttekinthetetlenné tudja tenni a kódot. Szerintem a goto-hoz hasonló elővigyázatossággal kell kezelni.
Nagyon veszélyes, ha egy osztály más dolgokat is tud produkálni, mint ami az interfésze alapján elvárható. Azt meg nem lehet elvárni, hogy dokumentációban rögzítse mindenki ezeket. Tipikusan a legjobb programozókból a legnehezebb doksit kicsikarni, pláne azt, hogy még karban is tartsák.
A másik gond, hogy gyakran használunk C librarykat, amiken nem lehet "átvezetni" a C++ exceptionjeit.
- A hozzászóláshoz be kell jelentkezni
Ó, na, ezt is jó tudni. Ugye java-ban explicite definiálod, hogy egy adott metódus Exception-t dob, pl.
public void myMethod() throws MyException;
így ott ez nyilvánvaló.
- A hozzászóláshoz be kell jelentkezni
Ilyen a C++-ban is volt (legújabb szabvány szerint deprecated), de csak futásidejű ellenőrzéssel. Ami egyrészt nincs ingyen, másrészt kb a hajadra kenheted... Szóval a kutya sem használta.
Ehelyett most van a noexcept, ami az az ígéret, hogy nem lesz exception. Fordítási időben továbbra sincs ellenőrzés, ha mégis van exception az továbbra is terminate hívást eredményez, viszont template trükkökkel már kideríthető a hívó oldalon, hogy a fv noexcept vagy sem.
Ha felmerülne a kérdés, hogy miért nincs fordítás idejű ellenőrzés, arra az a válasz, hogy nem igazán lehet értelmesen csinálni.
Nézzük a következő példát:
int sum(const vector<int>& v) noexcept
{
int sum = 0;
for (unsigned int i = 0; i < v.size(); ++i)
sum += v.at(i);
return sum;
}
Dobhat a sum fv exceptiont? Nem, mert az vector<int>::at(...) csak akkor dob ha túl vagy alul indexelünk. Viszont ez nem történhet meg.
Kitalálhatja ezt a fordító? Nem.
Tehát vagy van fordítási idejű ellenőrzés és minden ilyen kódba felesleges try-catch blokk (Java), vagy nincs ellenőrzés, és bízunk a programozóban. A C és a C++ általában az utóbbi utat választja.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Talán akkor itt vetném közbe, hogy úgy tűnik zsolt a régi vágású, konzervatív fejlesztői nézetet képviseli ahogy látom.
Modern C++ kódban nem okoz gondot nagy objektumok érték szerinti visszaadása, nem vagyunk többé az "out" paraméterek használatára kényszerítve (bár annak is van létjogosultsága). (Lásd még RVO, copy elision, move constructor)
Mint ahogy az exception-ökkel sincs különösebb gond, bár tény, hogy az exception safe programozás nem a legegyszerűbb, de ez igaz minden más nyelvre is (itt a GC sem feltétlen segít).
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Jól értem, hogy ő(k) elveti(k) például a factory patternt, míg pl. te úgy gondolod, hogy igenis használható dolog?
(persze, talán egy kissé sarkítva)
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Lehet az én képzelőerőm gyatra, de nekem a factory pattern polimorfizmussal jár együtt, ami C++ esetén valamilyen mutató (jobb esetben unique_ptr vagy shared_ptr) visszaadását feltételezi, ami egy kis objektum, így összeegyeztethető azzal amit zsolt mondott...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Akkor én vagyok lemaradva: ha valahol "objektumot" adsz vissza, az nem csak egy pointer átadást jelent (nyelvtől függetlenül)?
Mert én eddig abban a hitben éltem, hogy ez így működik.
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Nem. Szerintem még Javaban sem, ha az az objektum egy beépített típus, mondjuk int vagy double. Akkor nem szórakozik mutatókkal, érték szerinti átadás történik.
A C++ egyik alapvető tervezési célja volt, hogy a felhasználó típusai ugyanúgy működjenek mint a beépített típusok.
Azaz pl a következő két kód hasonlóan működik:
//1
{
int a = 1;
int b;
b=a;
}
//2
{
myint a = 1;
myint b;
b=a;
}
Mindkettő a stack-en hozza létre a változókat, és az értékadás után mindkét esetben az a és b változó két független objektumot tartalmaz melyeknek az értéke megegyezik. (value semantics)
Ami még fontos lehet ha már GC-ről beszélünk, hogy a blokk végén garantáltan és mindkét esetben lefut a és b destruktora és a memória felszabadul.
Ha viszont az értékadás másolás, akkor egy
vector<int> nums = loadNumsFromSomewhere();
utasítás nagyon drága lehet, mert a fv-ben feltöltött vektort le kell másolni a nums vektorba.
Erről beszélt zsolt, hogy ezt érdemes elkerülni.
Pl.:
vector<int> nums;
loadNumsFromSomewhere(nums);
Hála az RVO-nak és a move constructornak ez így önmagában nem feltétlenül gond.
Persze ha ezt egy ciklusban hívom ahol az előző nums vektort újra fel tudom használni, akkor megspórolhatok egy felesleges objektum létrehozást. De ez innentől már nem C++ specifikus kérdés.
Erről bővebben: http://ericniebler.com/2013/10/13/out-parameters-vs-move-semantics/
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Na jó, ez nekem innen kezdve kínai.
Én ott leragadtam úgy húsz éve, hogy elemi adatot adok vissza a függvényből, minden mást lerakok valahol és csak egy pointer megy vissza, ami az adott struktúrára mutat.
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Az a helyzet, hogy nem nagyon szeretjük, lehetőleg más design-ra törekszünk.
Persze ebben pont az a jó, hogy el lehet tőle térni, ha nagyon muszáj, mivel nem a nyelv tiltja.
- A hozzászóláshoz be kell jelentkezni
RVO / copy elision nagyon jó optimalizációs technika, ami lényegében ugyanazt csinálja, mintha "out" paramétert használnál, csak ugye elveszted a külön visszatérési értéket, ami exception-ök hiányában nem biztos, hogy jó ötlet.
Move konstruktor jó dolog. Egy konkrét esetre emlékszem, amikor nagyon jól jött volna, de még nem tudta a fordító. Gyalog kellett megvalósítanunk hasonlót. Azóta nem nagyon volt rá szükségem, főleg, hogy mostanában már nagyrészt Ultimate++-t használok, ott pedig a containerek egy részének lehet adatot mozgatva, konstruktor-futás nélkül értéket adni (pick semantics).
- A hozzászóláshoz be kell jelentkezni
"csak ugye elveszted a külön visszatérési értéket, ami exception-ök hiányában nem biztos, hogy jó ötlet."
Exception-ök hiányában valóban nem. De azok ott vannak ha akarod őket használni. :)
szerk.:
Megnéztem ezt a pick semantics-et az Ultimate++-ban... Mondanám, hogy szegény ember move konstruktora, de azzal, hogy a pick_-et const-ra definiálja elég veszélyesnek tűnik. (Ahogy le is írjék lejjebb.) A boost.move féle emuláció azért jóval kiforrottabb.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Igazából nem veszélyes, csak félrevezető (lenne, ha nem lenne a "#define pick_ const", mert akkor pick_ helyett const lenne az interfészben, holott pont az ellenkezője történik).
Az pedig nyilvánvaló, hogy az elmove-olt container elemeit már nem próbáljuk bizgetni :)
- A hozzászóláshoz be kell jelentkezni
Ezt te tudod, ha megnézted a headert vagy a doksit, a fordító viszont nem, és nem is szól.
Én tuti megszívnám, mert fel nem merülne bennem, hogy egy vektor értékadása nem copy hanem move...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Igen, ezért van külön minden containernek két verziója, pl. Array és Vector.
Array hagyományos copy constructoros, vector pedig move-ol.
- A hozzászóláshoz be kell jelentkezni
Az _automatikus_ hiánya?
Mert azt még el tudom képzelni, hogy manuálisan nem tudsz memóriát allokálni/felszabadítani, ez akár korlátként is felfogható lenne, de automatikus...
Hiszen ez az egyik lényege (meg időnként néhány probléma/bug forrása), hogy automatikusan kezeli a memóriát.
És bocs, de a lockolást végképp nem értem, hogy jön ide... Shared memória használatról beszélsz? C++-t addig ismerem, hogy cin, cout, meg hogy nagyjából felülről kompatibilis a C-vel.
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Lehet szo akar mutex lockolasarol is, akar file megnyitasrol/lezarasrol.
Pl.: Qt-ben van egy QMutexLocker nevu osztaly, ami konstruktorban var egy mutex pointert. Amint letrejon a locker, meghivja a lockot a mutexre. Amint megszunik, meghivja az unlockot ra (akkor szunik meg, amikor kikerul a scope-bol).
void C::f()
{
QMutexLocker ml( &mutex ); // Tegyuk fel, hogy van egy mutex nevu member a C osztalyban.
// Csinalunk mindenfele varazslast
} // Elengedi a lockot. Akkor is, ha elertuk, akkor is, ha kozben valami kivetelt dobott, es azert hagyja el a fuggvenyt.
"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series
- A hozzászóláshoz be kell jelentkezni
És Javában minek az alacsony szintű mutex? Ott a synchronized, sokkal magasabb szinten vagyunk.
- A hozzászóláshoz be kell jelentkezni
Ez csak egy konkret pelda akart lenni egy altalanosabb problemara.
Volt mar, hogy jol jott volna a RAII javaban nekem, bar a konkret peldara mar nem emlekszem.
"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series
- A hozzászóláshoz be kell jelentkezni
C#, lock, using statement, utobbi az IDisposable patternnel. Nem csak Java van a világon.
---------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Tudod, a C# a Sátán műve...
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
Ha szerinted a GC azért van, mert az emberek elfelejtik a delete operátort meghívni, akkor bizony van még mit tanulnod.
"Egy másik, hogy én személy szerint a GC-t leginkább értelmetlen korlátozásnak tartom" - miben korlátoz a GC?
- A hozzászóláshoz be kell jelentkezni
Elnézést, ha valami vallási meggyőződést sértettem a hozzászólásommal. Nem tudom, melyik hivataltól tetszik ítéleteket alkotni. Esetleg magához a Jóistenhez van szerencsém?
Mentségemül szeretném felhozni, hogy mi itten csak baráti fecsegéseket szándékozunk folytatni. A hozzászólásomat csak egyszerű gondolatébresztőnek szántam, nem egy minden aspektusra kiterjedő doktori disszertációnak.
Kérem, ha lehet, enyhítsen az ítéleten és engedje meg, hogy tovább végezzem alantas negyedosztályú szoftverfejlesztői tevékenységemet, ó Uram!
- A hozzászóláshoz be kell jelentkezni
Ok, tényleg kicsit indulatosra sikerült.
Azt azért elmondanád, hogy miben korlátoz a GC?
- A hozzászóláshoz be kell jelentkezni
Erről mindig az jut eszembe, hogy mi a magyar gondolkodásmód? Válasz: "Miért szerezzünk barátokat, ha ellenségeket is lehet" :))))
- A hozzászóláshoz be kell jelentkezni
Pedig ez hülyeség: az ellenség adott (gyk: mindenki a mostani mentalitás szerint :) ), azt nem kell szerezni.
Az utpKabel által feltett kérdésre én is kíváncsian várom a választ. Már csak azért is, mert ha jól emlékszem, ugyanezt én is megkérdeztem korábban.
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
+1
En is nagyon kivancsi vagyok!
- A hozzászóláshoz be kell jelentkezni
GC, mint a Java integráns része engem leginkább abban korlátoz, hogy nem tudom kikapcsolni.
Emiatt nem lehet vele determinisztikusan működő programot írni és rákényszerít egy teljesen rossz hatékonyságú memóriakezelési technikára. De ezt konkrétan leírtam fentebb.
Ja és nem gondolom, hogy maga a GC az ördögtől való lenne, csupán a kötelező jellegével van problémám.
- A hozzászóláshoz be kell jelentkezni
Kérdés az, hogy hova kell fejleszteni. Nyilvan más a követelmény egy mikrokontroller vagy más beágyazott, illetve egy nagyon erősen teljesitmenyorientalt feldolgozásnál, pl. Codexek, tömörítés, mint egy tok altalanos célú proframnal, ahol a CPU idő 95%-a azzal telik el, hogy var az user inputra a szoftver. Ezt igy leirni, hogy a GC azert rossz, mert nem determinisztikus, ezért hulljon a fergese, szerintem 2013 vege fele egy picit bátorságra vall. Mar az nem determinisztikus, hogy mi indulhat el meg a gépen, milyen gyorsan kotrod elo az adatot diskrol, hálózatról, az OS mit csinál a programmal, a CPU nem valaszt-e valami esetedben suboptimalis optimalizaciot, mert más generációra fordirottal, stb.
Masreszt, nem csak a Java az egyetlen GC-t használó nyelv.
----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
arrol nem is szolva, hogy egy multiprogramozott rendszer nem determinisztukus, de mar egy interruptokat hasznalo architectura sem az
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
Na, itt két dolgot meg kell különböztetni egymástól:
- a garbage collector, mint az automatikus memóriakezelés eszköze.
- garbage collected programozási nyelvek (pl. Java), amelyeknek kötelező része a garbage collector és automatikus memóriakezeléssel rendelkeznek.
GC létezik C-hez és C++-hoz is, ott természetesen nem kötelező használni, sőt egyazon alkalmazás használhatja egyszerre a garbage collected heapet, az unmanaged heapet, a stack-et, és tetszőleges számú custom allokátort is. A GC csak egy memóriakezelési módszer a sok közül.
én személy szerint a GC-t leginkább értelmetlen korlátozásnak tartom
Természetesen a lehetőségeket korlátozza az, ha egy nyelv kötelezővé teszi a GC-t, és ez bizonyos alkalmazási területeknél előnytelen. A "értelmetlen" résszel viszont vitatkoznék, hiszen az automatikus memóriakezelés kötelezővé tétele lehetővé teszi a nyelvnek:
- memory safety: a GC eliminálja a dangling pointerek lehetőségét, ha emellett a nyelvben nincs pointer aritmetika, akkor egyszerűen lehetetlen memóriahibát okozni, míg C++-ban bármilyen hiba jelentkezhet segmentation fault formájában (jobb esetben).
- type safety: a memory safety előfeltétele a valódi type safety-nek - hogy egy objektumot ne lehessen úgy használni, mintha az egy másik típusú objektum lenne. A C++ type safety-je "mindössze" annyi, hogy a compiler front-end hibaüzenettel visszadobja a programok egy részét.
- A hozzászóláshoz be kell jelentkezni
A garbage collector nem az automatikus memóriakezelés eszköze, hanem a szemétgyűjtőé.
A Java nyelvben nincs automatikus memóriakezelés, hanem szemétgyűjtés van.
A mai C++ projectekben nincsenek dangling pointerek több okból sem:
- nem használunk dinamikus memóriakezelést, csak nagyon, de nagyon ritkán
- memory leak detector azonnal szól, ha mégis valami félresikerülne
Tipikusan nincsenek memóriahibák sem, mert nem használunk pointereket és pointer aritmetikát sem. Ha mégis, akkor azt nagyon is ellenőrzött körülmények között, teljesen konkrét helyeken, agyontesztelve.
Type safetyvel a régi, 15 évvel ezelőtti pointeres rendszerekben komoly gond volt. Mostanában nem találkoztam komolyabb problémával, valószínűleg azért, mert a rendszert mindig eleve típusbiztosra terveztük, hogy soha ne legyen szükség castolásokra. Ehhez persze időnként szükség van magasabb szintű generikus programozásra, de ez többnyire pont az "ínyencfalat" része a munkának.
- A hozzászóláshoz be kell jelentkezni
Mit is nevezel automatikus memóriakezelésnek? A stacket?
memory leak detector azonnal szól, ha mégis valami félresikerülne
Nem tudom érzed-e a különbséget aközött, hogy valamilyen hiba egyszerűen lehetetlen, vagy hogy kényszeres valgrindezéssel lehet csak a problémát megelőzni?
nem használunk pointereket és pointer aritmetikát sem
Gondolom akkor az std::vector-t is az .at() metóduson keresztül indexeled, mert az ellenőrzött, ellentétben a [] operátorral, ami csak szintaktikai cukor a pointeraritmetikához.
- A hozzászóláshoz be kell jelentkezni
Nagyon nehéz ezt az egészet elmagyarázni. Úgy lehet megérteni igazán, ha rendesen dolgozol ilyen C++ projectben. Sajnos azok számára, akik mostanában tanultak programozni, ez legalábbis sci-fi, de inkább a teljesen lehetetlen kategória. Pedig a beágyazott rendszerek fejlesztése nagyrészt ezekkel a primitív módszerekkel történik. És persze sok más C++ project is.
A C++ automatikus memóriakezelése alatt azt értem, amikor az egymást tartalmazó objektumok allokálása, a konstruktoruk, destruktoruk futása és a deallokálása automatikusan zajlik. Iskolai példákban ezt a stacken szokták próbálgatni és valahogy asszociálódik az embereknél a stackkel, de ez a heapen is működik vagy egy containerben.
Memory leak detectort célszerű az allokátor szintjére tenni fejlesztési időben, valgrind inkább profiler unix-like rendszerekre.
std::vectort konkrétan nem szokásom használni, de szerintem a [] operátort mindenképpen metódusként érdemes megírni, ami legalább ASSERT-ekkel védett. Az általam használt containerekben mindenesetre így van. Gyakorlatban egyébként jellemzően nem ez a terület okoz problémákat.
Az én tapasztalatom egyébként az, hogy a programozók nem valami korlátozandó idióták, akiket inkább le kell kötözni, nehogy hibázhassanak. Ha a te hozzáállásod lenne általános, már rég betiltották volna a személyautókat és csak sínen közlekedő automatizált eszközökön lehetne közlekedni. Ahol meg nincsen sín, oda ne akarjon menni senki.
- A hozzászóláshoz be kell jelentkezni
Szemelyeskedes es frazispufogtatas helyett:
par soros mintakon egyik-masik.
Ez sokkal beszedesebb, mint egymas kepessegeit becsmerelni:)
- A hozzászóláshoz be kell jelentkezni
Természetesen nem azért született, viszont szépen eltakar számos dolgot, amit el szokás felejteni.
Nem az eltakarás a baj, hanem az, hogy nem tudja mindig eltakarni, és itt már meg is találtuk is a kolléga által említett indeterminisztikus jelleget - ami egyébként létezik pedáns programozónál is, csak tetten érni nehezebb.
Fel nem tételezve, hogy itt megfordulnak ilyenek is, de létezik olyan ember, aki szerint a GC úgy jó, ahogy van. Számukra intő szó lehetne a GC hangolására (ideértve a kihagyásra és azonnali startolásra) tett kísérletek és tanácsok webes nyoma, azzal az intelemmel kiegészítve, hogy a jvm puszta megnövelésével esélyes lehetsz a GC ciklus vámján elveszíteni, amit a réven nyertél - de az intő szó hitháborúk csatazajába vész. Gépből meg úgyis mindig van még gyorsabb.
- A hozzászóláshoz be kell jelentkezni
Nem igazán értem ezt az eltakarásos dolgot, tudnál erre példát mondani? Mit kellene a GC-nek eltakarnia? A működése elég egyszerű, legalábbis kóder szinten, ha egy objektumra nincs referencia, akkor a GC előbb vagy utóbb kitakarítja. Hogy mikor és hogyan, az rajta (és a paraméterezésén) múlik. A nemdeterminisztikusság az világos, ugyanis a GC amikor darál, akkor egy időre megállítja az egész rendszert, ezért kell már az elején ésszel fejleszteni, és folyamatosan mérni. Az, hogy mikor áll le, az majdhogynem csak rajta múlik, és világos, hogy ez bizonyos típusú programoknál problémát jelent.
jvm puszta megnövelése: itt a heap-re gondoltál?
- A hozzászóláshoz be kell jelentkezni
Végtelenségig leegyszerűsített példa a takarásra az elrontott finalize() metódus. A GC minden más szemetét összeszedi, ezért egy ideig nem tűnik ki, hogy finalize() miatt egy titkos hulladéktemető van kialakulóban.
Csak nő a finalizálandó sor hossza, lopva a cpu-t és heapet, aztán akár egy ártatlan műveletnél kiakad a rugó.
A GC az egészben a fogadott prókátor, aki a védhetetlent is védené.
Igen, pongyola voltam, a heap növelése értendő a jvm növelése alatt.
- A hozzászóláshoz be kell jelentkezni
A finalize() részt nem igazán értem. Alapvető, hogy a finalize() metódust nem használjuk kb. sohasem, mert az nem destruktorként működik... Vagy van még
valami úri huncutság, amiről nem tudtam eddig?
- A hozzászóláshoz be kell jelentkezni
Nem, mindent látsz.
Nagyjából ugyanolyan alapvető az, hogy finalize() arra van, hogy ne használjuk, mint az, hogy a destruktort meghívjuk, hogy a visszatérési értéket ellenőrizzük, máshol, hogy a buffer túlcsorgatását kívédjük, hogy a szélsőértékekre külön figyelünk...
A mndenhol rendelkezésre álló logok meg heapdumpok a tanúk az ilyen triviák betartására:
...
finalization candidates="2655" enqueued="2636"
finalization candidates="2698" enqueued="2678"
finalization candidates="2620" enqueued="2600"
finalization candidates="2720" enqueued="2700"
finalization candidates="2642" enqueued="2623"
finalization candidates="2696" enqueued="2677"
...
És ez szinte még csak a keretrendszer eredménye.
- A hozzászóláshoz be kell jelentkezni
Milyen keretrendszer ez? A mi logjainkban soha nem láttam még ilyet...
Kiegészítés: egyébként köszi a megjegyzést, most jobban bele is ásom magam a finalize működésébe, mindig tanul érdekeseket az ember. Elsőnek mondjuk ezt találtam:
http://www.oracle.com/technetwork/articles/javase/finalization-137655.h…
- A hozzászóláshoz be kell jelentkezni
A finalize metódus alapvetően nem helyettesítője a C++ destruktornak, mivel a finalize metódus 1 dologra való, míg a C++ destruktor legalább 2-re. Szóval én egy use case-t ismerek, amikor a finalize metódust kell használni:
Ha egy managed heapen található objektum unmanaged heapen található memóriablokkot birtokol - tehát csak memóriát, semmi egyéb erőforrást -, akkor ennek felszabadítására a finalize a jó megoldás.
Igen, Javára lefordítva ez azt jelenti, hogy szerintem a finalize metódust csak JNI-vel együtt értelmes használni.
- A hozzászóláshoz be kell jelentkezni
Igen, erre a referenciaszamlalos smartpointerek vannak.
Mire is van a GC? :)
- A hozzászóláshoz be kell jelentkezni
A -> B
B -> A
ez ellen nem véd :) egyébként az egész java nyelvnek és VM-nek van egy logikája a memóriakezelést illetően. Ebből egy részt kivenni és azt önmagában elemezni nem sok
értelme van szerintem.
- A hozzászóláshoz be kell jelentkezni
A reference-counting is a garbage collection egy módja, ami ha annyira jó lenne, akkor nyilván a Java is alapvetően ezt használná, viszont a valóság az hogy:
- a tiszta reference-counting leakel ha hivatkozási körök vannak.
- a reference-counting lassabb, mint egy tracing GC, mivel a reference-count állandó állítgatása több időt igényel, mint néha végigszaladni az összes elérhető pointeren.
- A hozzászóláshoz be kell jelentkezni
Ugy tűnik, oda kellett volna raknom egy smiley-t.
Persze, a ref-count nem jó körök esetén, vagyis az esetek csak egy részét oldja meg.
Viszont, hogy lassabb lenne, azt nem tudom elfogadni. Miről is van szó? Az overheadeEgy atomic-increment vagy atomic-decrement smart pointer konstruktor/destruktor hívás esetén. És ez mivel is versenyzik? Egy threaddel, ami fogja a rendszert random időnként. Kezdjük azzal, hogy egy szálú alkalmazás esetén semmilyen overheadje sincsen a ref-countnak. Egyébként is, az atomic inc/dec nagyon gyors tud lenni (persze ez oprendszer és CPU függő, de akkor is).
Mondjuk lehet, hogy az a bajom, hogy nem értek a Java-hoz. De nehéz elképzelni olyan esetet, amikor ne tudnék olyan megoldást tervezni, amiben elkerülhető a körkörös referencia, okos designnal.
- A hozzászóláshoz be kell jelentkezni
A Java GC-jét nem ismerem, de a .NET GC alapból a következőt csinálja (de tudtommal van még vagy 5 másik GC technika, a .NET 4.5-ben megint optimalizáltak valamit a nagy alkalmazásokra, szóval ha a hülyeséget beszélek, valaki javítson légyszi):
Az objektumokat eleve 3 szinten csoportosítja: soha nem GC-zett, már egy ciklust túlélt, több ciklust túlélt. Eleve, ha nem szükséges, a második kategóriában lévőket már nem is birizgálja, ha nincs rá nagyon szükség, mivel általában úgy is azokat az objektumokat kell leghamarabb felszabadítani, amik még nem éltek túl GC-zést. Amit igen, az valószínűleg maradandóbb. -> Már nem kell az összes objektummal foglalkozni és csak akkor kell velük foglalkozni, ha valóban GC-zés van, szemben a refcounttal, ahol mindig van valami minimális matek.
De egyébként a GC-nek van más előnye is: egyszer teszteltem olyannal, hogy folyamatosan foglaltam le X megányi adatot. A program kb. 2X+konstans mennyiséget használt folyamatosan. Nem teszteltem, hogy mi van akkor, ha nincs elég ram, de gondolom, akkor nem cserélgette volna a két memóriaterületet, hanem egyet pucolt volna. Ezt egy értelmesebb (vagy kettő) GC meg tudja oldani anélkül, hogy nekem egy sor kódot írnom kellett volna. Natív kódnál maximum, ha valaki megírja magának.
----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Mondjuk lehet, hogy az a bajom, hogy nem értek a Java-hoz.
Némi rosszindulattal azt mondhatnám, az a bajod, hogy nem értesz a C++-hoz. Például nagyvonalúan úgy csinálsz, mintha a manuális memóriakezelés ingyen volna. Bizony a malloc/free-nek (vagy new/delete) könyvelést kell vezetni a kiadott és a szabad memóriablokkokról, időnként syscallokra kell várakoznia, hogy memóriát kapjon az operációs rendszertől, vagy hogy épp visszaadjon neki. Bizonyos use case-eknél (jellemzően a sok apró objektum allokálása esetén) a GC gyorsabb lehet a kézi memóriakezelésnél (és itt még nem beszélek referencia-számlálásról), pusztán azért, mert kevesebb könyvelést kell vezetni a memóriakezeléshez. A memóriafoglalás pl. leggyorsabb egy stop-and-copy GC-vel (csak egy pointert kell növelni), a takarítás ideje pedig az élő objektumok méretével arányos.
A reference-counting költsége pedig éppen abban áll, hogy minden pointermásolásnál és minden pointer megszüntetésnél írni-olvasni kell a memóriát. Egy GC-s megoldásnál csak a memória lefoglalásáért kell fizetni. Ha nem érzed meggyőzve magadat, végezz méréseket! Itt van pl. egy csokor, amit valaki más végzett.
- A hozzászóláshoz be kell jelentkezni
"Némi rosszindulattal azt mondhatnám, az a bajod, hogy nem értesz a C++-hoz."
Némi rosszindulattal azt mondanám, hogy a kezdők szoktak személyeskedni.
- A hozzászóláshoz be kell jelentkezni
Érdekes blog, itt egy cikk cserében:
"As long as their applications will be running on systems equipped with more than three times as much RAM as required, then garbage collection is a reasonable choice. However, if these systems will have less RAMor if the application will be competing with other processes for physical memory, then practitioners should expect garbage collection to exact a substantial performance cost."
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Szerintem itt másról beszélünk. A cikk sajnos nem mond nekem semmit, mert nem derül ki belőle, hogy mit is mértek pontosan.
A malloc() drága, ebben egyetértünk. De a GC ugyanúgy kell, hogy hívjon malloc()-ot.
A malloc() és a free() ugyanis mindig lassú. Viszont a smart pointernek semmi köze a malloc-hoz.
Teszem azt, hogy leírod, hogy shared_ptr a = new int(12); Két malloc() hívódik itt. Előszor is a new-en keresztül meghívott malloc()-kal te foglasz memóriát.
A shared_ptr tartalmaz egy másik malloc-ot is, és egy ref count incrementet. Ha copy cstrja hívódik, akkor nincs másik malloc, csak ref-count művelet. Destruktor hívásnál van egy free() a ref-count mellett, ha elfogytak a referenciák.
Namost, ha a shared_ptr helyesen van megírva, akkor a belső malloc() lefut kb 2000 cpu cycle alatt. Ugyanis shared_ptr által hívott malloc mérete fix, ezért remekül lehet poolozni, ami egy konstans idő alatt végrehajott allokáció. Ez a konstans időben végrehajtott allokáció egy mutex hívásból és egy stack/láncolt lista műveletből áll.
Abban az esetben lehet szar a shared_ptr, ha ugyanazt a shared_ptr-t érték szerint gyakran másolgatjuk, és mindezt tőbb thread között. És ezt nem egy, hanem millió kicsi objektummal csináljuk.
De még ekkor sem nagyon szar. Ha az atomic inc/dec drága az adott platformon, akkor persze baj van.
Nekem úgy tűnik, hogy keverd a szezont a fazonnal.
A naív, memória-poolok nélküli malloc()-ozást hívod shared_ptr-nek, és ezt hasonlítod a GC-hez.
Gondolom, hogy a GC implementációk erősen memoria pooloznak. De ezt te is megteheted, GC nélkül is.
A fair összehasonlítás nem shared_ptr + naív malloc vs GC, hanem a shared_ptr + fast malloc vs GC lenne.
Remélem érthető volt :)))
- A hozzászóláshoz be kell jelentkezni
De a GC ugyanúgy kell, hogy hívjon malloc()-ot.
Pont hogy nem.
- A hozzászóláshoz be kell jelentkezni
Ha jól sejtem, neki az az info hiányzik, hogy java-ban (de talán c#-ban is) a VM kapásból lefoglalja a paraméterekben megadott memóriaterületet,
és ebből gazdálkodik, tehát malloc hívás csak a program futásának elején történik.
- A hozzászóláshoz be kell jelentkezni
Csak remélni merem, hogy ez nem így van. :)
(Mi történik, ha kevés a memória? Akkor sem hív még malloc-ot? Nem arról van-e szó, hogy megadhatod mi az a memória ami mindenképp kell, vagy várhatóan kell, így optimalizálva a futást kicsit?)
Mondj egy olyan dolgot amit a java-c# meg tud tenni memóriakezelés közben és ami c/c++ esetén nem lehetséges. Én egy dolgot tudok: elvileg át tudja pakolni az objektumokat a memóriában, megszüntetve a fragmentálódást. Hogy ezt valóban megteszi-e azt nem tudom, de nem tűnik egy olcsó műveletnek.
Ha jól sejtem az az infó hiányzik, hogy a malloc hívás nem csak egy vékony wrapper a kernel hívás felett, egész sok mindent megoldhat magában, akár még kapásból lefoglalhatna hatalmas területeket is induláskor.
Mint ahogy a free sem feltétlen adja vissza a memóriát az OS-nek. (Sőt, azt is megkockáztatom, hogy ilyet soha nem tesz...)
Csak egy példa, hogy mi mindent csinálhat egy malloc implementáció:
http://goog-perftools.sourceforge.net/doc/tcmalloc.html
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Nem, ez úgy működik, hogy megadod a max heap méretet. A java induláskor befoglal egy akkora címtartományt. Ha túlléped a programodban, akkor kapsz egy
out of memory exception-t, tehát pont a java fejlesztők azok, akik rá vannak kényszerítve arra, hogy figyeljenek arra, hogy a programjuk mennyi memóriát
használ.
Igen, pl. fragmentáció kompresszió, stb. de mint korábban mondtam, az egész előnye az, hogy ezt a sok mindent elrejti a fejlesztő elől, akinek a kódolással
kell foglalkoznia, nem azzal, hogy most adott objektumot hol hoz létre, hogy ad át, mit kezd a fragmentálódott memóriával, stb, stb.
Olvasnivaló pl. innen:
http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos…
http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepap…
- A hozzászóláshoz be kell jelentkezni
Most lehet én nem értek valamit, de ha induláskor befoglalja a megadott memóriát, és soha többet nem foglalhat többet az azt jelentené, hogy minden java program fix mennyiségű memóriát használ a teljes futása alatt.
Utoljára mikor eclipse-t indítottam nekem nem ez volt a tapasztalatom...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Nekem még a virtuális memóriakezelésnél meséltek olyasmit, hogy van az a köcsög operációs rendszer, amely néha hajlamos olyan pimaszságokra is, hogy hiába kér a program ramot, csak akkor adja a memórialapokat, ha azt tényleg használatba is veszi, addig sóher módon megtartja magának...
----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Már értem miről beszél, csak éppen akkor egy kicsit össze vissza.
"Bizony a malloc/free-nek (vagy new/delete) könyvelést kell vezetni a kiadott és a szabad memóriablokkokról, időnként syscallokra kell várakoznia, hogy memóriát kapjon az operációs rendszertől, vagy hogy épp visszaadjon neki."
Ehhez képest a GC azért tök jó, mert az az elején lerendezi a syscall-t...
Merthogy nyilván a GC-nek is kell könyvelést vezetnie. Nem mellesleg egy normális malloc implementáció sem kéreget területeket byte-onként az OS-től.
Szóval nem, ez még mindig nem egy előny a GC oldalán...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Egy stop-and-copy GC pl. nagy könyvelést nem csinál, sokkal kevesebb könyvelés kell neki, mint egy malloc/free-nek. A működési elve röviden: a szabad terület a heapen mindig összefüggő, memóriafoglaláskor egyszerűen visszaad annyit a szabad terület elejéből, amennyit kértél. Ha a szabad terület elfogy, akkor az élő objektumokat átmásolja egy másik ugyanakkora heapfél elejére, így ott megint összefüggő lesz a szabad terület, és itt igazából nem is a szemetet kell gyűjteni, hanem az értékes memóriát.
Egy olyan allokációs mintánál, ahol sok kis rövidéletű objektum allokálódik (amelyek lehetnek különböző méretűek), simán verni fogja a kézi malloc/free.
Az pedig nem igaz, hogy a GC csak az indításnál kér memóriát az operációs rendszertől, a legtöbb implementáció képes a heapméret növelésére.
- A hozzászóláshoz be kell jelentkezni
"Az pedig nem igaz, hogy a GC csak az indításnál kér memóriát az operációs rendszertől, a legtöbb implementáció képes a heapméret növelésére."
Ennek örülök, mert nem tűnt hihetőnek.
Ez a stop-and-copy GC meg jól hangzik, ezt tényleg nem lehet GC nélkül, de nehezen hiszem, hogy bizonyos nagyon behatárolt alkalmazásokon kívül a való életben használható lenne.
Vagy esetleg van olyan Java, C#, akármi implementáció ahol ez a default?
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Ha jol tudom mind C# mind a Java generational garbage collectort hasznal, ahol a legfrissebb generacio takaritasa hasonlo elven mukodik.
- A hozzászóláshoz be kell jelentkezni
Mi a vélemény a cikkről amit fentebb linkeltem?
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
A lényeg, hogy a heap méret a maximálisan megadottnál nagyobb nem lesz (-Xmx paraméter a sun/oracle
java vm-nél)...
- A hozzászóláshoz be kell jelentkezni
Az, hogy megadhatsz egy maximumot megint más kérdés, eddig előre lefoglalt területet emlegettél.
Ami ha jól látom egy -Xms paraméter.
Persze gondolom megadhatod ugyanazt a számot mindkettőnek, de azért ez eléggé ortogonális attól, hogy GC vagy nem GC.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Címtartományt foglal be, ha jól emlékszem, és szerintem ebből foglal memóriát. De jó
kérdés, hogy pontosan hogyan működik, ennyire nem mentem bele a részletekbe, soha nem
volt rá szükségem. Meg lehet admin a kezdő lefoglalt heap méretet, és a maxot is.
- A hozzászóláshoz be kell jelentkezni
Off: izé... ebben a szövegkörnyezetben mit takar az "ortogonális"? Pár jelentésével (merőleges, ortogonális utasításkészlet stb.) már találkoztam, de egyik sem illik ide.
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Talán a "független" lenne a jó szinonima ebben a mondatban.
Egyébként pont ebben az értelemben szerepel az "ortogonális utasításkészlet"-ben: "„Ortogonális” olyan értelemben, hogy az utasítás típusa és a címzés módja egymástól függetlenül változhat." (Wiki)
Azt akartam csak mondani, hogy az, hogy állíthatok kezdeti-meg maximum memóriafoglalást az teljesen független attól, hogy GC-t vagy nem GC-t használok. (Mert pl semmi nem akadályoz meg abban, hogy olyan malloc implementációt használjak, ahol szerepel ez a két paraméter.)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Talán "független", személyes zsargonban :)
--
♙♘♗♖♕♔
- A hozzászóláshoz be kell jelentkezni
Erre tippeltem én is, csak előtte feltúrtam a netet, hol találok ennek megfelelő magyarázatot, de nem nagyon jött egy sem. :)
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Tessék, ahol tudok segítek: orthogonal.
Nem saját agyszülemény, még akkor sem, ha esetleg pongyola volt a megfogalmazás.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
[troll on]
Rendszergazda portálon nem elvárás, hogy értsék. ;)
Válogasd meg a szavaidat! :D
- A hozzászóláshoz be kell jelentkezni
Nem az iptables mélylélektanáról folyt a diskurzus, ezért gondoltam... Lehet rosszul. :)
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Végeredményben a pongyolaságára akartam utalni. Nagyjából sejthető volt, hogy mit akarsz. :)
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
utpKabel leljebb elmagyarázza...
- A hozzászóláshoz be kell jelentkezni
Igen, igy mukodnek a C++-os memoria poolok is.
Foglalnak elore jo sok memoriat, es abbol adnak annak, aki ker.
Ha kifogy a hely, akkor megint lefoglalnak egy nagy blokkot.
- A hozzászóláshoz be kell jelentkezni
Akkor honnan veszi a memoriat? :)
Ne vicceljunk mar, a heapbol kell foglalni memoriat, nincs mese. A GC talan statikusan allokalt bufferekbol dolgozik???
- A hozzászóláshoz be kell jelentkezni
Az operációs rendszertől kér.
A hiba ott lehet a gondolatmenetedben, hogy a heap az nem egy eleve létező valami, hanem éppen a malloc és a free valósítja azt meg. Ezek az operációs alacsony szintű rutinjait (pl. mmap, munmap) használják, amelyekkel az operációs rendszer lehetővé teszi, hogy a címtér egy részét használhassa a process. Ezzel a területtel aztán a malloc és a free gazdálkodik, hogy a programozónak tetszőleges méretű memóriablokkokat adhasson, és hogy közben ne pazarolja túlságosan a memóriát.
Egy GC-nek semmi szüksége arra, hogy mallocot hívjon, egy valamire való GC közvetlenül hívja az operációs rendszer rutinjait, majd maga gazdálkodik az adott területen.
Egy C programban lehet egyszerre unmanaged és garbage collected heap is, ilyenkor előbbit a malloc/free, utóbbit a garbage collector kezeli.
- A hozzászóláshoz be kell jelentkezni
Most már azt hiszem értem, minek hoztad fel azokat a memória poolokat. Amikor azt mondtam, hogy sok kisméretű objektum allokálása esetén a GC gyorsabb, mint a malloc/free, akkor én nem arra gondoltam, hogy sok azonosan kisméretű allokálása esetén, hanem az egyes objektumok mérete nagyban változhat, de mégis sok kicsi és nem néhány többszázmegás chunk. Na erre varrjál nekem memory poolt!
- A hozzászóláshoz be kell jelentkezni
Akkor miért van?
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Hogy legyen min flamelni!
----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Azt tudja a refcount is!
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Szegeny ember GC-je... :)
----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Itt leírtam, mi előny származhat abból, ha a GC a nyelv megkerülhetetlen része. További előnyök, amelyek akkor is érvényesek, ha csak a kód egy része használ GC-t:
- egyszerűbb contract: Egy C vagy C++ API tervezésekor mindenhol megfelelően specifikálni kell, hogy mikor kinek a felelőssége az paraméterként átadott, vagy visszatérési értékként visszaadott objektumok felszabadítása. GC használatakor ez nem kérdés.
- egyszerűbb memóriakezelési minták: a) mehet stackre, vagy túl kell élni-e ezt a függvény? b) lehet-e preallokálni a hívónál és oda beírni az eredményt, vagy mondjuk polimorf a visszatérési érték? c) elég egyszerre egy referencia az objektumra? => auto_ptr / unique_ptr d) ha osztott a birtoklás, akkor vajon aciklikus-e a hivatkozási lánc? e) ha kialakulhat körkörös hivatkozás, meg lehet-e törni a láncot alkalmasan választott a weak pointer elhelyezésével? -- ezeket a kérdéseket mind végig kell gondolni kézi memóriakezelésnél, GC-snél pedig nem.
- ha az előbbi kérdések mindegyikére 'nem' a válasz: akkor már csak egy tracing GC segíthet.
- adott memóriakezelési patternre lehet, hogy éppen egy adott GC fajta a leggyorsabb.
Végülis az 1-2 pontokra rá lehet fogni, hogy az ember lusta átgondolni, hogy mikor kellene a dolognak felszabadulni, és oda tenni a delete-et / free-t. De azért azt vegyük észre, hogy néha nem hátrány, ha az ember bitbaszakodás helyett az eredeti probléma (aminek megoldására a program készül) megoldásával foglalkozik.
- A hozzászóláshoz be kell jelentkezni
Biztos én kódolok túl sokat C++-ban, de ezek nem okoznak komoly gondot.
Kezdjük ott, hogy nem szórakozunk szabad pointerekkel (ownership témában legalábbis). Az 1-es pont tehát kilőve.
Többnyire érték szerint adunk vissza, adunk értékül, stb.
Ha polimorfizmus kell, akkor unique_ptr.
Az állandóan fikázott refcount-os shared_ptr-t nem tudom mikor használtam utoljára, de idén biztos nem. Nem állítom, hogy haszontalan, de messze nem olyan gyakori mint ahogy egyesek képzelik.
A nagy mumus, a körkörös hivatkozás meg tizenakárhány éves C++-os működésem alatt egyszer jött elő, de akkor is én voltam béna.
Valószínűleg egyébként azért alakult ki ez a shared_ptr körüli hisztéria, mert egyesek azt hiszik, hogy úgy kell C++-ban programozni mint Java-ban, csak mindenhol shared_ptr-rel.
Persze mondhatod, hogy unique_ptr-shared_ptr nagyon új dolog, de az az igazság, hogy pl Qt alatt pointerekkel zsonglőrködve is lehet gondolkodás nélkül memory-leak mentes kódot írni.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Lásd még a 370 millió dolláros rakétát, ami egy integer overflow miatt zuhant le.
Az emberek alapvetően hibáznak és tévednek. Ezért van a nyelv, ami első védővonalként megvédi a fejlesztőt a hülyeségeitől,
azután a fejlesztőeszköz (és a beépített vagy telepíthető statikus kódanalizátorok), a kód konvenciókat betartató scriptek,
a code review, a pair programming, a különböző szintű tesztelés, stb. egy rakás védővonal van, amit felhúzunk, hogy biztosítsuk,
hogy a kód stabil, szép, és jól működő legyen.
- A hozzászóláshoz be kell jelentkezni
az a raketa pont a nyelv "vedovonala" miatt zuhant le, ugyhogy nem jo pelda :)
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
A vicces, hogy kikapcsolták az assert-et. Na, azt nem kellett volna :)
- A hozzászóláshoz be kell jelentkezni
milyen assertet?
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
"in failure due to an error in the software design caused by assertions having been turned off, which in turn caused inadequate protection from integer overflow. "
- A hozzászóláshoz be kell jelentkezni
a reportban nincs benne ez a kifejezes: http://www.di.unito.it/~damiani/ariane5rep.html
inkabb ennek hiszek, mint a wikipedianak. :-)
roviden:
volt egy overflow (float64 -> int16), es erre az ada dobott egy exceptiont (vedovonal, ugye!)
az inercia navigaciot kezelo szoftver erre valaszul beleirta az eepromba a hibakodot es leallt (lol).
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
Azért az is sok mindent elmond, hogy ez teszteléskor nem jött elő csak élőben...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Milyen tesztelés? :))))
- A hozzászóláshoz be kell jelentkezni
nem volt benne a specifikacioban...
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
A kódot módosítás nélkül vették át egy korábbi, kitesztelt modellből. Sajnos az a modell nem volt olyan gyors, mint az újabb, így nem voltak olyan nagy értékek, amik túlcsordulhattak volna.
- A hozzászóláshoz be kell jelentkezni
Na de könyörgöm, én sem pakolom tele az összes kódomat unit tesztekkel, de azért egyszer le szoktam futtatni őket, csak, hogy lássam, hogy működik...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Meg a másik előnye a szabad memóriakezelésből adódik.
A fiúkkal is egyetértek. A tévedést úgy lehetne kiküszöbölni, hogy vagy a fordító ellenőrzője kifinomultabb és szól, hogy valami galiba lehet. Vagy bekapcsolunk olyan funkciót, hogy a memória kezelés bizonyos részét vagy teljes egészében a rendszer kezelje.
Az lenne az igazi, hogy egy kezdő számára egy csomó mindent megcsinál maga a rendszer automatikusan, mint pl a java. Viszont ahogy tanul az ember, jó pár dolgot ő venne a kezébe és úgy játszana már a memória kezelés résszel, ahogy azt a profik teszik.
Persze nem tudom, hogy ez így jó lenne e vagy így lenne a legjobb. Ami most a lényeg, hogy nem így van. Ami most történhet a legjobb esetben egy szétszórt, kapkodó embernél, hogy megy a program, mégha optimizálatlanul is. Ez tekinthető már jónak is. Ha meg úgy veszük, hogy rosszabbul sikerült annál, mint ami a legjobban kihozható belőle, akkor az is igaz.
De tényleg illik és érdemes megfontoltan, jól programozni, ahogy azt a programozói nyelv is megkívánja. Tény, hogy valóban nem akárkinek való.
- A hozzászóláshoz be kell jelentkezni
"Egy dilettáns akkor is zavaros kódot fog írni, ha helyette kezeli a rendszer a memóriát."
Hej, azok a WebSphere AS logok, amelyekből kiderül, hogy a finalizer tartja életben és egyszersmind féken az egész miskulanciát...
- A hozzászóláshoz be kell jelentkezni
Leginkább azért, mert a tapasztalataim alapján a C++ programozók jó részének fogalma sincs az OO gondolkodásmódról. A másik, hogy a C++ egy NAGYON nehéz nyelv,
nagyon sok mindenre kell figyelni, amit a modernebb nyelvekben már régen megoldottak. Éppen ezért egy kezdőnek, aki korábban Pascal-ban programozott, soha de soha
nem ajánlanék C++-t, egyszerűen azért, mert pont olyan gányoló c++ programozó lesz belőle, mint a nagy többség, én meg szeretnék jót neki :) Lehet akár a python-nal
is kezdenie, lényegében mindegy, de c++-szal, én nem kezdenék...
- A hozzászóláshoz be kell jelentkezni
Te megint OO desing-ról beszélsz (nagyrészt), nem a programozási nyelvekről.
Éppenséggel a Pascal egyáltalán nem rossz alap, mert pl. nincsen gc viszont vannak pointerek, getmem/freemem és osztályok.
Tovább nem ragozom.
- A hozzászóláshoz be kell jelentkezni
Részben. Én azt látom a gyakori problémának, hogy sokan beleugranak egy nehéz nyelvbe, és mivel az idejük nagy része azzal megy el,
hogy a nyelvi nehézségekkel küzdjenek, pont az OO design-ig nem fognak eljutni, vagy csak nagyon későn. Ennek az eredménye pedig
összetákolt-összegányolt, fejleszthetetlen, átláthatatlan kód lesz...
Tehát én azt mondom, hogy mielőtt elkezd C++-szal szívni, tanulja meg az OO gondolkodásmódot. Hogy erre melyik nyelvet választja, az rajta múlik. Én a java-t javasoltam,
más a python-t (vagy akár a C#-ot), mindegyik rendben van erre a célra, bár lehet, hogy a python egyszerűbb, csak attól a c++ még távolabb van szintaxisban, mint a java-tól..
Még egy megjegyzés: a pascal nem lenne rossz alap, csak olvasd el fent, hogy ő mit szeretne. Delphin nőtt fejlesztő feldobálja egy panelra a komponenseket, aztán rákattint,
és beírja a kódot. Na, ez az, amit én saját kódban nem szeretnék látni...
- A hozzászóláshoz be kell jelentkezni
+1
Aki tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Ez egy nagyon leegyszerűsített példa volt. Csak annyi előnye volt ennek, hogy a Formmal és a bennük lévő elemek kódszinten való kiépítését nagyjából már elvégezte, amit csak módosítanom és kiegészítenem kellett. Egyik legnagyobb előnye az volt, hogy láttam, hogy hogyan épül fel kódszinten a form. Ez olyasmi, mint C++-ban az, hogy felül van a header rész, lejjebb különböző deklarációk, aztán jött a main() és a többi osztály is. Ha látom már a szerkezetét, a felépítését, akkor már jobban kiismerem magam és ez a későbbiekben nagyon fontos.
Igen, a C++ azért is nevezek, mert itt még nekünk kell például megírjunk a konstruktorokat, destruktorokat, amit ha jól emlékszem mások szavaira, a java automatikusan elvégzi.
- A hozzászóláshoz be kell jelentkezni
Most próbálok nem úgy írni, hogy beszólásnak érezd, de nagyon nehéz lesz. A lényeg, hogy pont azzal van a gond, amit csinálsz, azaz hogy keveredni fog
az adatmodell, a vezérlés, a megjelenítés egy osztályba, aztán egy idő után ember legyen a talpán, akik kibogozza, ahogy az egyik form átnyúl a másikba
valami adatért. Ez nem jó. Értem én, hogy lehet, értem én, hogy így csinálták, de ettől még nem lesz jó :)
- A hozzászóláshoz be kell jelentkezni
Erre lehet olyan megoldás, hogy van egy fájl, ott legyen mondjuk egy x változó deklarálva. Edit mezőbe beírja a felhasználó és az elküld gomb megnyomására ennek a változónak értéket ad vagy megváltoztatja. Ugyanezen a formon vagy másikon lenne egy adatok megtekintése gomb, ahol beolvassa a változó értékét az elején említett fájlból, ha létezik értéke. Ha nem, akkor vagy nem jeleníti meg vagy üresen hagyja a mezőt vagy amit akarunk.
Gondolom ilyesmire gondolsz. Átláthatóvá lehet tenni, az értékeket csoportosítva is lehet akár több fájlban is tárolni. Vagy ha érdemesebb, akkor adatbázisban tárolni, mint pl a Mysql.
Osztályokkal, különböző ciklusokkal is lehet ilyeneket játszani.
Régen Delphiztem és akkor mégcsak egyszerű programokat írtunk. Ezért nagyon minimálisan kellett ügyelnünk az átláthatóságra.
Ha mondjuk nem említed, akkor lehet, hogy én is beleestem volna a későbbiekben ebbe a hibába.
- A hozzászóláshoz be kell jelentkezni
Igen, mintha lenne egy trade-off a mernokok szakertelmeben.
Akik C iranybol jonnek, nem ertenek az interface-hez es az OOP-hez.
A javasok meg szar lassu kodot irnak,haha.
Ritka, akik mind a ket iranyt jol ismeri es erti.
- A hozzászóláshoz be kell jelentkezni
mindkettőt el lehet hasaltatni. Az alacsony szintű nyelvet azzal, hogy akkor most át kellene rakni egy 8 processzoros architektúrára,
és hozzá kellene pattintani még XYZ feature-t mondjuk 1 hónapon belül, a magas szintű nyelvet meg azzal, hogy oké, de ez hogy fog
futni majd az embedded gépen, már berendeltünk 500-at belőlük..
- A hozzászóláshoz be kell jelentkezni
WinFormsot így 2013 környékén felejtsük már el.
----------------
Lvl86 Troll, "hobbifejlesztő" - Think Wishfully™
- A hozzászóláshoz be kell jelentkezni
Szerintem hanyagold a C++-t.
Olyan mint a heroin. Nem tudsz lejonni rola.
Es kezdoknek uberszopas, a legjobb, hogy nem is ertik miert.
- A hozzászóláshoz be kell jelentkezni
Es kezdoknek uberszopas, a legjobb, hogy nem is ertik miert.
4-5 hónaposan a felállás négykézlábról orra bukás az mi? Uberszopás?
A kérdező, valamit meg szeretne tanulni. És kész. Ebben kért tanácsot. Alapoknak akkor a GNU C++ és egy jó IDE. PL.Eclipse vagy a NetBeans, de jöhet a wxWidgeté is. (Kedvencemet nem ajánlom vim.
És ha már megy a C++ akkor jöjetne pl a www.wxwidgets.org (Na azt hiszem annak van is egy nagyon jó IDE-je). És a www.zetcode.com- on találhat tuttorialokat step-by-step az alapoktól a tetrisz játékig.
wx-nek van wxFB néven formBuilderja is.
Na üdv.
- A hozzászóláshoz be kell jelentkezni
Ha már wxWidgets:
wxWidgets + CodeBlocks IDE + wxSmith hármas egy komplett vizuális fejlesztőeszköz.
De a Lazarusnak is +1
- A hozzászóláshoz be kell jelentkezni
Van aki könnyen megtanulja, van akinek meg 50 év múlva sem fog menni a C++. Én inkább az voltam, aki sokáig nem vette komolyan és ez meg is látszott.
Mondjuk én szeretem a printf, scanf függvény használatát. Nem tudom, hogy például cout esetén mennyire lehet megadni, hogy egy számot például 212.23200 formában írja ki, a printf esetén például ezt könnyedén meg lehet tenni. Bár a cout-ot fogom használni, ha csak 212.232 formában akarom kiírni. Szóval mikor mire van szükség.
Valóban sokat lehet szopni. Viszont lehet C++ dolgokkal foglalkozó fórumot olvasgatni és segítséget is kérni, ha tényleg szükséges. Nagyon sokmindenből lehet tanulni és így az ember gondolkodása is annak megfelelően változik.
- A hozzászóláshoz be kell jelentkezni
Azt megjegyezném, hogy cout-al még könnyebben meg lehet adni. (setprecision() és társai)
- A hozzászóláshoz be kell jelentkezni
define könnyebben. :)
Nekem még mindig utána kell néznem a setprecision-nak és társainak, míg a printf megy csípőből.
De van egy rakás alternatíva Qt-ben, boost-ban ami printf like, és készül már valami szabványos megoldás is...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Én sem tudom fejből, hogy pontosan hogyan kell használni.
Egyébként milyen készülő szabványos megoldásra gondolsz? Úgy tudom, az std:: névtér alól ezek a bigyók eléggé szabványosak.
(Hát mondjuk igaz, tényleg az a könnyebb, amit tud az ember)
- A hozzászóláshoz be kell jelentkezni
Szabványos printf like megoldásra gondoltam, a készülő alatt meg erre:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3716.html
Lehet nem a legfrissebb verzió annyira nem követem.
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
a cin/cout borzadvany az a c++ szabvany egy nagyon rosszul sikerult resze :-)
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
Sokan mondják ezt, de erre csak azt tudom mondani amit Stroustrup: még senki sem javasolt egy jobbat...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
printf :D
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
Format string attack. :)
- A hozzászóláshoz be kell jelentkezni
Nekem a printf, scanf bevált. Csak akkor fogom használni a cin, cout függvényeket, hogyha van amire szükségem lesz.
- A hozzászóláshoz be kell jelentkezni
Azért az iostream kicsit több szolgáltatást nyújt mint a printf...
"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o
- A hozzászóláshoz be kell jelentkezni
Variadic template-es printf.
A C++-os iostreamnek alapvetően két problémája van:
- boilerplate syntax (a printf-hez képest)
- A formázási opciók a stream állapotához tartoznak.
- A hozzászóláshoz be kell jelentkezni
A variadic template printf sem az igazi.
Egyreszt sok fordito nem tamogatja a C++11-et (persze ez nem a nyelv hibaja), masreszt meg erosen noveli a kod meretet, mert majdnem minden hivasbol kulon fuggveny fog fordulni. Neha ez baj.
- A hozzászóláshoz be kell jelentkezni