- Befutott a megígért HRV-mérés a Withings órájára
- Egy szenzor, két zoomkamera: újraírta a Huawei a mobilfotózás történetét
- Samsung Galaxy S22 Ultra - na, kinél van toll?
- Elkészült és telepíthető az Android 16
- Apple Watch Sport - ez is csak egy okosóra
- iPhone topik
- MIUI / HyperOS topik
- One mobilszolgáltatások
- Samsung Galaxy S25 Ultra - titán keret, acélos teljesítmény
- Google Pixel topik
Új hozzászólás Aktív témák
-
dabadab
titán
válasz
xavix13 #2799 üzenetére
A tanár gépén nem működik a pont, csak a felkiáltójel és a helyesírásellenörző is elromlott?
(vagy inkább:
)
A feladatkiírásból egyébként nem derül ki, hogy mitől függ, hogy ki nyer - megpróbálok abból a feltevésből kiindulni, hogy az, akinek a dobásainak (ami a feladat elején még lövés volt
) összege a nagyobb.
Elég elszomorító ez a színvonal
Ami elsőre szemet szúr, hogy az egy .... tiz változók tök fölöslegesek meg teljesen feleslegesen duplikát (tízlikelt
) kódhoz vezet, eleve a játékos számait is a jatekos[] tömbbe kellene beolvasni egy ciklusban.
C++ kódból én az ilyen C-s tömböket kiutálnám, tessék container template-eket használni, illetve a magyar változónevek meg kommentek szintén olyanok, amit az ember nem csinál.
-
xavix13
őstag
Sziasztok!
6 hete tanulok c++ programozást a fősulin, és holnap zh-t írok belőle.
A tanár kiadott egy mintafeladatot amihez hasonló lesz holnap.
Nagyjából sikerült megoldani, egy működőképes programot írni, de ha valakinek van egy kis ideje, és megtudná mutatni a helyes, "szép" megoldást azt nagyon megköszönném. -
yossarian14
tag
válasz
EQMontoya #2797 üzenetére
A c++ kódban a ciklusmag üres, direkt tesztelés céljából.
A Java kódom sokkal gyorsabb még úgy is, hogy a ciklusmagban komoly dolgok folynak (egy adatszerkezetet építek fel a memóriában a beolvasott szöveg alapján):
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
process(line);
}Köszi a segítséget!
-
EQMontoya
veterán
válasz
yossarian14 #2796 üzenetére
Ez nem lesz lassú, ha értelmesen processzálsz. Este tudok csinálni pár tesztet, de ennek nem kellene lassúnak lennie.
Nem a ciklusmagon belüli rész lassú? -
yossarian14
tag
Sziasztok!
Miért van az, hogy Java-ban sokkal gyorsabb egy fájl soronkénti beolvasása, mint C++ ban?
Így néz ki a kódom:
void process(string fileName) {
cout << ++j << ": " << fileName << endl;
ifstream file(fileName);
string line;
while (getline(file, line))
{
}
}Elég nagy mennyiségű, 70GB-nyi szövegről van szó, úgyhogy elég fontos lenne a gyors olvasás és elég jelentős a különbség. Esetleg tudtok javasolni valami gyorsabb módszert c++-ban?
-
Destructo
senior tag
Sziasztok!
Egy projekt megvalósításában szeretném kérni valaki segítségét Budapesten , az én programozási tudásom sajnos meghaladja az elvárt szintet. Egy pár alkalommal talákoznánk , megbeszélnénk , megírnánk a már nagyjából összeállt kódot/projectet. Természetesen honorálnám a dolgot .
Kérlek titeket arra aki tudna segíteni írjon egy privát üzenetet a továbbiakhoz!
Köszönöm , József !
-
Zsolt1
tag
Köszi a segítséget neked is és EQMontoyanak is, a dinamikus tömböt csak azért raktam bele, mert gyakorlaton is ez volt és nem volt erre vonatkozó instrukció, hogy kell-e vagy nem, de közben mástól is megkaptam javaslatban, hogy inkább nem kéne
.
A kommentezésen gondolkoztam hogy kiszedem, mert tényleg zavaró lehet, de valahogy nem volt már erőm egyesével törölgetni, mert komment + "dokumentációval" (pár sor txt-be) kell majd leadnom és inkább írtam párhuzamosan, most viszont kiszedtem(egyébként pte).
Megcsináltam azokat, amiket mondtatok(legalábbis remélem, hogy pontosan azokat), viszont még mindig lefagy valamiért futás után és nem is adja hozzá a sort (ugyan azt a tömböt kapom vissza a művelet után). A codeblocks most nem dob semmilyen hibaüzenetet fordítás alatt. Kiírattam futás közben és elvileg megcsinálja a másolást ott ahol kell, a 4 sorban viszont kiíratáskor ez már nem látszik. main.cpp Matrix.h Matrix.cpp -
LordX
veterán
Nem azt a függvényt deklaráltad friend-é, amit végül definiáltál (más a paraméter), ezért kapod ezt a hibát a fordítótól.
Egyébként a kód kicsit túlbonyolított, még lesz ezen felül is dolgod vele:
- a konstruktor nx5 méretű adatot vár, nem fog működni más mérettel
- Temporálisat referenciaként visszaadni HATALMAS hiba (operator+; add vissza érték szerint)
- a dinamikus tömbök dinamikus tömbje se nem gyors, se nem hibatűrő, erősen ajánlott helyette egy tömböt használni, és az indexelésnél számolni pozíciót.BTW, hol tolják ezt a magyarkodást, fáj olvasni a kommenteket
-
Zsolt1
tag
Sziasztok!
Egy operátor túlterheléses feladatban szeretnék egy kis segítséget kérni. Az lenne a feladatom, hogy + operátorral oldjam meg, hogy egy mátrixban az első 0 sorba beillesszek egy tetszőleges sort és az operátor túlterhelés legyen barát függvénye az osztálynak. Ez alapján a két oldal (oldal1, oldal2) alapján próbáltam megoldani a dolgot, de nem sikerül rájönnöm, hogy mi lehet a hiba.
A kód ami nem működik: main.cpp, matrix.h, matrix.cpp A hibalista amit a CodeBlocks dob: [link]
Valamiért azt írja, hogy az arr tömb és az n változó privát és pont ezért nem értem, mert a friend hozzáférés módosítóval ellátott függvény elvileg eléri az osztály privát adattagjait is és úgy csináltam az egészet, mint ahogy a két linkelt oldalon is le van írva + ahogy órán is működött. Ha valaki végignézi ezt az egészet, annak előre is köszönöm! -
LordX
veterán
válasz
ToMmY_hun #2787 üzenetére
Ha előre tudod a szükséges típust, és csak egyféle kell egy adott helyen, akkor minek tárolod őket egy közös mapban?
Külön map az Effector-nak, Joint-nak, stb, a "factory" (off: én nem hívnám factorynak, mert a factory nem tulajdonosa a legyártás után az objektumnak, ez inkább valami storage) meg a típus alapján template:
Storage<Effector> effectors;
Storage<Joint> joints;
effectors.create("effector1", 1);
joints.create("joint1", 2.0, true);
auto &x = effectors.get("effector1");
auto &y = joints.get("joint1");Teljes kód itt: [link]
Ja, én nem szeretem a naked mutatókat; smart pointer, observing pointer objektum (asszem jön egy standard C++17-el) vagy referencia, különben nem egyértelmű, ki destruálja az objektumot, ha már nem kell.
-
ToMmY_hun
senior tag
válasz
EQMontoya #2788 üzenetére
Ez jogos, de nem látok rá esélyt, hogy fog. A matematikai számításokhoz a karrészek hosszára, szélességére van szükség, azokból pedig létrehozhatok bármennyi példányt és az működik a jelenlegi koncepcióval. Persze ha van valami frankó ötleted a megvalósításra, azt szívesen meghallgatom és ha nem tart napokig a megvalósítása, akkor meg is csinálom.
A template tippet köszönöm, utána fogok járni mielőtt újra a kódhoz nyúlnék.
-
-
ToMmY_hun
senior tag
válasz
EQMontoya #2786 üzenetére
Azért nem template class, mert nem tudom mi az, nem találkoztam még vele.
Nagyjából másfél hónapja kezdtem el a projektet nulla c++ tudással (és kevés OOP-vel is, mivel villamosmérnökként nem tananyag az objektum orientált programozás), de igyekszem kihozni a maximumot magamból és a programból is. Inkább segítséget mit kritikát kérnék, mert abból többet tanulok és végső soron ez a cél.
"Ha PartSubC mellett lesz egy PatrSubD, ami szintjén jó Neked, akkor 2x fogsz castolni, és még pár módosítás múlva láncolt listát bejáva fogsz castolni (
), vagy lesz egy PartSubVirtualCD osztály, amiből leszármazik mindkettő, tehát az objektumstruktúrádat b@szod szét fölöslegesen?"
Nekem van egy Part ősosztályom, abból származnak le a specifikusak, mint Effector, Joint, ArmPart és Body, ezek egy robotkar részeit képezik. A kereső metódus az ezeket tároló map-ben keres és mindig csak egy adott objektum típusra lesz szükségem, amit majd elkérek a factory-tól. Szerintem így sosem lehet szükségem dupla kasztolásra, vagy rosszul látom?
-
EQMontoya
veterán
válasz
ToMmY_hun #2784 üzenetére
RapidXML-t próbáltam, de nem kezeli a string objektumot, csak karaktertömböt, abból meg nem kérek ha nem muszáj.
A a void* azért lenne jobb, mert később még szeretném kiegészíteni a factory-t más osztályokkal is. Emvy kolléga jól látja, a Part-ból származtatott osztályok különböző tagváltozókkal, metódusokkal rendelkeznek, így a sima Part pointer visszatérés még nem elég.
A factory miért nem template class?
Az pedig, hogy a partban nincs megfelelő infó ennek eldöntésére, tervezési hiba.Ha PartSubC mellett lesz egy PatrSubD, ami szintjén jó Neked, akkor 2x fogsz castolni, és még pár módosítás múlva láncolt listát bejáva fogsz castolni (
), vagy lesz egy PartSubVirtualCD osztály, amiből leszármazik mindkettő, tehát az objektumstruktúrádat b@szod szét fölöslegesen?
-
ToMmY_hun
senior tag
Rendben, köszi. Viszont ha már belelendültem a kérdezgetésbe, akkor azt is megkérdezném hogy egy viszonylag könnyen használható XML Parser lib-et tudtok ajánlani? RapidXML-t próbáltam, de nem kezeli a string objektumot, csak karaktertömböt, abból meg nem kérek ha nem muszáj. Sebesség itt sem mérvadó, mert beállításokat fogok abból betölteni egyetlen egyszer, a program indításakor.
-
ToMmY_hun
senior tag
A a void* azért lenne jobb, mert később még szeretném kiegészíteni a factory-t más osztályokkal is. Emvy kolléga jól látja, a Part-ból származtatott osztályok különböző tagváltozókkal, metódusokkal rendelkeznek, így a sima Part pointer visszatérés még nem elég. Végülis a dynamic_cast működik és a miatta keletkező overhead sem probléma, mert csak az inicializálásnál lesz használva.
Szerk: Akkor inkább legyen az objektum típusát tartalmazó tagváltozó és ellenőrizzem azt?
-
EQMontoya
veterán
Értem, mire gondolsz, de alapvetően az ilyen esetekre is lehet valamilyen attribútumot, vagy egy virtuális függvényt (ez jobb, főleg ha az ősben van deffiniálva mondjuk, és false-t ad vissza, a megfelelő leszármazottban meg true-t), és az lényegesen elegánsabb (és gyorsabb) megoldás, mint a cast. Ha reflection-szerű megoldásra van szükség c++-ban, az gáz, azért van többszörös öröklés, hogy minden megfelelő interface-szel rendelkezhessen az adott osztály.
Emiatt én leginkább hacknek tartom, ami ugyan lehetséges az adott nyelven, de alapvetően nem ajánlott, és inkább tervezési hibára vezethető vissza.
Szerk: Meh, hamarabb írtam a választ, mint az edited.
-
válasz
EQMontoya #2779 üzenetére
Hat vagy igen, vagy nem. En ugy kepzeltem, hogy a problemaja az, hogy a leszarmazottakat nem 'Part'-kent akarna hasznalni, hanem a leszarmazottak specialis tulajdonsagaira van szukseg.
Tehat ha van Part, meg PartSubC1 meg PartSubC2, akkor neki adott esetben csak a PartSubC2 a megfelelo, es PartSubC1 nem.
Persze az lehet, hogy a Part-nak van egy virtualis fuggvenye, ami kozli a sajat nevet/tipusat, es a problema meg is van oldva -- ez az egyik megoldas a sok kozul. A dynamic_cast egy masik. A lenyeg, h runtime check az kell.
-
válasz
ToMmY_hun #2777 üzenetére
Egyreszt, void * helyett visszaterhetnel Part *-al is.
Ez a szokasos ko/kontravariancia problema. Ha a maped Part*-okat tartalmaz, es forditasi idoben nem tudod leszukiteni a potencialisan tartalmazott leszarmazottak tipusat, akkor nincs mese, futasideju ellenorzest kell valahol csinalni. Ezt sok ponton meg tudod oldani, de a vege tuti az lesz, hogy valahol ellenorizned kell azt, hogy az adott sztring kulcshoz tartozo ojjektum megfelelo tipusu-e.
Erre a dynamic_cast egy lehetseges megoldas, de akar tarolhatod a mapban is a tipusinformaciot, ahogy jolesik.
-
ToMmY_hun
senior tag
Sziasztok!
Ismét lenne egy kérdésem, amire szeretnék egy viszonylag szép megoldást találni (szakdoga lesz belőle). Van egy metódusom egy Factory DP implementációban, amely keres több map-ben tárolt objektum között, amelyeket egyedi string azonosít. Minden map a Part osztály leszármaztatott osztályainak példányait tárolja, de ebből van 4 féle. A metódus ebből kifolyólag void pointerrel tér vissza, amit a felhasználás helyén vissza cast-olok a kívánt típusra. Ez szép és jó, de nem garantálja semmi a típusbiztos cast-olást. Ennek ellenőrzésére tudnátok ajánlani valami jól bevált módszert? A dynamic_cast<>()-ot néztem, de van ennél esetleg jobb?
Köszi előre is!
-
ToMmY_hun
senior tag
Én szívesen vállalom. Az én elképzelésem szerint evolválhatna a leírás egy nyugodt, de nem túlságosan lassú ütemben. Amikről kezdetben érdemes lenne írni a felhasználható irodalom, példaoldalak és az IDE kiválasztása, beállítása. VS, CodeBlocks tapasztalataim vannak, de a NetBeans-t is sikerült belőni, nagyjából tudom melyik IDE mit tud, mikor melyiket célszerű alkalmazni. Amiben nincs tapasztalatom az a rendelkezésre álló lib-ek, szóval azt majd szépen sorjában. Rám bízzátok, vagy lesz a feladatra alkalmasabb emberke?
-
htc07
addikt
Sziasztok!
"olvasd el a téma összefoglalót!" felirat ugyan virít a topikban jobb felül, de hol találom az összefoglalót?
Elkezdenék foglalkozni a c++-al (volt már vele dolgom régebben, de kb. én magyaráztam a tanáromnak hogy mi miért hogy).
Nem idegen a programozás, php megyeget, szal a lényeg, tudnátok javasolni valami könyvet/ebookot, tutorial videókat, amik értelmesen magyaráznak, akár az alapoktól, és egy relatív használható tudást tudnék belőle elsajátítani?
Angol nem gond, de preferálnám a magyart.
-
LordX
veterán
válasz
ToMmY_hun #2768 üzenetére
Használd inkább a map::emplace függvényt, az pont arra van kitalálva, hogy új elemet hozz létre a konténerben:
PartCoordinates.emplace(std::piecewise_construct, std::forward_as_tuple("B"), std::forward_as_tuple(10.3f, 45, 456.0f, 54));
A te módszereddel készül egy temporális Matrix objektum, amiből (és a temporális std::string-ből) készítesz egy szintén temporális std::pair, amiből végül az insert move-construct-olja a konténerben a végleges eredményt. Ugyanez igaz az std::string-re is, 2 extra temporális jön létre a kódban. (Mondjuk ilyen kicsi stringek esetében mindegy, de ha nagyobb, mint az SSO méret, akkor meglepően gyenge lesz ennek a kódnak a sebessége.)
Amit én írtam, ott nincs semmilyen temporális objektum, minden forwardolva van. A szintaxis kicsit béna, mert valahogy meg kell különböztetni, hogy az egyébként 5 paraméter közül melyik a kulcs melyik az érték paramétere, de a többi konténerben csak simán felsorolod a konstruktor paramétereket:
std::vector<Matrix> foo;
foo.emplace_back(1,2,3,4); -
ToMmY_hun
senior tag
válasz
ToMmY_hun #2767 üzenetére
Meg is válaszolnám a kérdésemet:
A map deklarációja:
std::map <std::string, Matrix>PartCoordinates;
Első körben a [] operátorral szerettem volna új elemet hozzáadni, az így nézett ki:
PartCoordinates["B"] = Matrix(10.3f, 45, 456.0f, 54)
Ebben az esetben szükség van mindkét elemnél a default konstruktorra, de mátrixnál nem szerettem volna ilyet alkalmazni. A map insert tagfüggvényét használva megoldható a dolog, így néz ki:
PartCoordinates.insert(std::pair<std::string, Matrix>(std::string("B"), Matrix(10.3f, 45, 456.0f, 54)));
Remélem segít valakinek.
-
ToMmY_hun
senior tag
Sziasztok!
Egy szerintem érdekes kérdésem lenne, remélem nektek is tetszeni fog.
Szeretném megoldani azt, hogy egy map-ben olyan osztályt adjak meg value-ként, amelynek nincs default konstruktora. Lenne ötlet arra vonatkozólag, hogy ezt hogyan lehet szépen megvalósítani? A public default konstruktor semmiképp sem játszik.
Köszi előre is!
-
Karma
félisten
válasz
EQMontoya #2762 üzenetére
Egy 2 GB-os fájlnál ez a stratégia már nem nagyon fog működni (Windowson, 32-bites bináris esetén).
Nekem egyébként nem világos, hogy a történet merről kezdődik: van egy blokkokra (három soros egységekre) tagolható, gyakorlatilag végtelen fájl, amit "el kéne forgatni" úgy, hogy egy blokk hosszú legyen és végtelen széles?
A blokk magassága fix?
Mert akkor meg lehet csinálni minimális memóriaigénnyel és a bemenet egyszeri olvasásával. Ha külön ideiglenes fájlba gyűjtesz minden egyes sort (ez blokkmagasság darab fájlt jelent), mindegyiknek szigorúan a végére írsz (minden 3*m+i-edik sort a bemenetről, ahol m a blokk száma, i pedig a fájl indexe), majd a legvégén összefűzöd a három fájlt, kész is az eredmény.
Ha a blokkmagasság nem ismert, akkor a feladatnak nincs sok értelme.
-
válasz
EQMontoya #2760 üzenetére
Na jó, csak azt kellene csinálnom, hogy az alábbi strukturában van egymás alatt rengeteg, nagy mennyiségű adat:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 1516 17 18 .......
.....................
..........................................
....................
....................Na és ezt kellene az elpőbb felvázolt módon egymás mellé pakolgatni, hogy így nézzen ki:
1 2 3 4 5 16 17 18 ....... .....................
6 7 8 9 10 ..................... .....................
11 12 13 14 15 ..................... .....................Szóval akkor marad a fapados megoldásom?
-
EQMontoya
veterán
válasz
HussarF #2759 üzenetére
Jól értem, hogy Te most a file közepébe szeretnél írni?
Ez nem fog menni sehogy, ne erőlködj.
Ha odaseek-elsz, akkor onnantól írsz a fileba, bármi is van utána.Az ilyen problémákat úgy szokták kezelni, hogy az összes adat, amit menteni akarsz, memóriában van, és mindig kiírod a teljes filet. A beleseekelés írt fileba csak nagyon speciális körülmények között értelmes dolog.
-
Na még egy kis tanácsot szeretnék kérni.
Ugye fájlbaírás során egy olyasmit szeretnék, hogy a belolvasott adatokat először egy ehhez hasonló formátumban írom ki:1 2 3 4 5
6 7 8 9 10
11 12 13 14 15Az ezután kezdődőeket viszont rendre az első/második stb. sor után:
1 2 3 4 5 16 17 18 19 20
6 7 8 9 10 21 22 23 24 25
11 12 13 14 15A kiírásnál \n-el törtem a sort. Kinéztem, hogy ofstream::seekp és ostream::tellp függvényekre lenne szükségem. A probléma, hogy miután a seekp-vel visszaállítom a kurzort az 5-ös után, az nem kezdi el az 5-ös után írni a számokat, hanem amint kiderült: 1 2 3 4 5 \n 6 7 8 9 10 \n 6 7 8 9 10 szerűen látja a fájlt és ha visszaállítom az 5-ös mögé, akkor egyszerűen felülírja az utána következőket.
Most az jutott eszembe, hogy akkor, ha tudom ,hogy egy sor milyen hosszú lesz, akkor annyi töltelék karaktert beszúrok, hogy majd azt írja felül, de ez elég fapados megoldás.
Nem tudtok valami elegánsabb megoldást erre, vagy nincs valami célfüggvény vagy közismert algoritmus? Nem nagyon találtam semmit :/
Köszi -
A cél az lett volna, hogy a megadott input textfájlhoz hasonló formátumból a whitespace karakterekkel elválasztott string-eket szedje ki egyenként, és azokkal külön operáljon, utána mehet tovább a következőre.
Most string-gel ezt meg tudom csinálni egyszerűen? Van ilyen parancs hozzá? Vagy csak a getline? Ez utóbbi esetben akkor olvassam be soronként és strtok-kal tördeljem fel és úgy vegyem külön a karakterláncokat?
-
dabadab
titán
válasz
EQMontoya #2753 üzenetére
Hahó, printf, nincs ott se típusellenőrzés, se cast, adsz neki valamit és majd azt valahogy értelmezi, akkor is, ha annak úgy semmi értelme. Szóval nem hogy csak lefordul, de még csak warning se lesz (hacsak nem olyan nagyon okos a fordító, hogy külön ismeri a printf-et, végigparse-olja a format stringet és megnézi, hogy értelmes adatokat adtál-e meg neki - de nem tudom, hogy ezt tényleg megcsinálja-e bármelyik fordító (Visual Studio biztosan nem))
-
dabadab
titán
válasz
HussarF #2750 üzenetére
"De amit nem értek, hogy valahol mégis csak beolvassa így is a string-be"
Nem a stringbe, hanem egy random tárterületre, ugyanis a printf egy char *-ra számít, ehelyett megkapja a string értékét (nem magát a C-stílusú stringet, ami jelen esetben egyetlen nullla karakterből állna, mert üres, hanem kompletten a belső változók értékeit) és ezt értelmezi pointerként (printf szintén). Szóval valami tök random helyre írsz a memóriában és onnan is olvasol.
-
EQMontoya
veterán
válasz
HussarF #2748 üzenetére
Jujj, azért ez a pattintott C korszak.
Fscanf: char*-ba tudsz vele olvasni.
Ha stringbe szeretnél olvasni c++ módon, akkor valahogy így próbálkozz:int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
}
myfile.close();
}else cout << "Unable to open file";
return 0;
} -
Sziasztok!
Kicsit kezd kiégni az agyam, ezért gondoltam kérek egy gyors segítséget.
A problémám, hogy valamiért nem akar működni bizonyos körülmények között a cout string-en. Tehát beolvasok egy fájlból string objektumba stringeket, utána a cout nem adja vissza. Bár ennél lehet kicsit komplexebb a probléma. Mutatom a kód részletet, amit kivettem az eredetiből tesztelésre:A testing.txt tartalma:
thr gbe jtk
fff thr lopMi lehet a baj? Falra mászok már tőle, egyszerűen nem értem, hogy miért csinál úgy, mnitha semmit nem olvasna be a fájlból....
-
jattila48
aktív tag
-
EQMontoya
veterán
válasz
jattila48 #2745 üzenetére
RVO != move, az egyik a standard része, a másik meg compiler okosíáts, de tény, hogy néha hasonló a végeredménye
A vektoros példa pedig szerintem koncepcionálisan is f@szság, nem a függvénynek kell követnie a move szemantikát, hanem a visszaadott objektumnak kell moveolhatónak lennie. -
jattila48
aktív tag
A http://nyelvek.inf.elte.hu/leirasok/C++0x/index.php?chapter=5 ELTE jegyzetben a move szemantikánál találtam az alábbi, szerintem hibás példát:
std::vector<int> && function() {
std::vector<int> ret; // ret feltöltése jó sok adattal
return ret;
}Azt akarja bemutatni, hogy hogy kell rvalue referenciát visszaadni, a költséges másolás elkerülése érdekében. Csakhogy a ret lokális változóra vonatkozó referenciát ad vissza, ami megszűnik visszatérés után. Ugyanígy lokális változóra vonatkozó lvalue referenciát, vagy pointert sem szabad visszaadni. Ha mindenképpen a move szemantikát akarja használni, akkor az
std::vector<int> function() {
std::vector<int> ret; // ret feltöltése jó sok adattal
return std::move(ret);
}lenne erre megfelelő. Még jobb, ha egyszerűen érték szerint adja vissza.
std::vector<int> function() {
std::vector<int> ret; // ret feltöltése jó sok adattal
ret;
}A modern fordítók RVO optimalizációt hajtanak végre (se copy, se move ctort nem hívnak), vagy ha ez nem lehetséges, akkor automatikusan a move szemantikát használják (a ret-et std::move nélkül is rvalue-nak tekintik, mert visszatérés után megszűnik). A return std::move(ret) elveszi az RVO optimalizáció lehetőségét, és a költségesebb move szemantikát alkalmazza, ezért ne használjuk. Azt azért furcsállom, hogy egy ilyen súlyos hiba benne maradhat egy ELTE jegyzetben. Egyébként általában is nagyon ritka esetben kell rvalue referenciát visszaadni. SOHA ne adj vissza lokális változóra vonatkozó pointert, lvalue vagy rvalue referenciát!!!
Vélemények? -
jattila48
aktív tag
válasz
Retekegér #2734 üzenetére
A Counter & a fv. visszatérési értékének típusa, vagyis Counter típusra "mutató" referencia. Eddig is így írták, az általad mutatott "ellenpéldában" is. int &rSomeRef = someInt; utasításban az & nem a SomeRef-hez tartozik, hanem az int-hez. Vagyis SomeRef egy int & típusú változó, egy int-re "mutató" referencia.
-
jattila48
aktív tag
válasz
ToMmY_hun #2739 üzenetére
Ha exceptiont dob a konstruktor, akkor nem jön létre az objektum (és így a destruktora sem fog meghívódni). A new lefoglalja a megfelelő tárhelyet, majd mikor a ctor exceptiont dob, fel is szabadítja azt. A factory függvényedben kell lekezelni az exceptiont, és NULL-t (vagy nullptr-t, vagy "üres" smart pointert) visszaadni, ha a konstruktor exceptiont dobott.
class MyClass{
....
};
MyClass * factory(int arg){
MyClass *p=NULL;
try{
p=new MyClass(arg);
}
catch(...){{
return p;
}Az egyszerűség kedvéért írtam raw pointer visszatérő értéket, igazából a factory fv.-nek inkább std::unique_ptr<MyClass> smart pointert célszerű visszaadni.
Egyébként a paraméter ellenőrzést már a factory fv.-ben is elvégezheted, de akkor csak ezzel célszerű objektumot létrehozni, ctor közvetlen hívásával nem, mert az nem ellenőrzi a paramétereket. Ezt úgy lehet elérni, hogy a ctor-t protected-dé teszed, a factory-t pedig az osztály friend-jévé, vagy statikus tfv.-évé.MyClass * factory(int arg){
if(arg>0){
return new(std::nothrow) MyClass(arg);
}
else{
return NULL;
}
} -
ToMmY_hun
senior tag
válasz
EQMontoya #2736 üzenetére
Először is köszönöm a választ.
A feltételes példányosítás alatt pedig azt értem, hogy csak akkor történjen meg a példányosítás, ha bizonyos feltételeknek ( például tömeg nagyobb mint nulla, hossz nem negatív) megfelelnek az argumentumok.
Végülis ha a factoryban csinálok minden példányosítani kívánt osztályra egy publikus kreátort, akkor rendben van.
-
EQMontoya
veterán
válasz
ToMmY_hun #2735 üzenetére
A feltételes példányosítás alatt pontosan mit értesz?
Különböző paraméterszámú konstruktorok: az egyik variácó, hogy vannak opcionális paraméterek. Ennek a sorrend miatt az a hátránya, hogy ha megadsz egy opcionálisat, akkor az összes előtte lévőt is meg kell adnod, nem kapják meg a default értéket. Illetve asszem, c++14-ben meg tudod oldani pythonos módon, tehát hogy minden paraméternek van default értéke, és név szerint adsz néhánynak.
A másik, hogy settereket írsz az extra paraméterekre, és egy konstruktorod van, de ez alapvetően béna.A factorydon meg nyilván annyi publikus függvény lesz, amennyiféle konstruktorod van, ezt szerintem semmilyen nyelven nem úszod meg.
-
ToMmY_hun
senior tag
Sziasztok!
Kezdő vagyok C++ téren, de egy kicsi tapasztalatom van OOP területen (java). Szeretnék feltételes példányosítást csinálni úgy, hogy a példányosítandó osztályok különböző számú és típusú bemeneti paramétereket várnának. Az lenne a kérdésem, hogy ezt hogyan lenne érdemes szépen megoldani? Egyelőre factory design patternt kezdtem el implementálni, de a különböző paraméterszámú konstruktorok miatt elakadtam.
Előre is köszi a segítséget.
-
Retekegér
MODERÁTOR
C++ könyv példaprogramjával kapcsolatban lenne egy kérdésem, adott az alábbi kód az inkrementáló operátor túlterhelésének szemléltetésére:
#include <iostream>
class Counter
{
public:
Counter();
~Counter() {}
int GetItsVal() const {return itsVal;}
void SetItsVal(int x) {itsVal = x;}
void Increment() { ++itsVal;}
const Counter& operator++();
private:
int itsVal;
};
Counter::Counter():
itsVal(0)
{}
const Counter& Counter::operator++()
{
++itsVal;
return *this;
}
int main()
{
Counter i;
std::cout << "The value of i is " << i.GetItsVal() << std::endl;
i.Increment();
std::cout << "The value of i is " << i.GetItsVal() << std::endl;
++i;
std::cout << "The value of i is " << i.GetItsVal() << std::endl;
Counter a = ++i;
std::cout << "The value of a: " << a.GetItsVal();
std::cout << " and i: " << i.GetItsVal() << std::endl;
return 0;
}Nos, az operator++ függvény számomra nem egészen világos, konkrétabban a "Counter&". Hivatkozás lenne?
-
katona.jozsi
aktív tag
Sziasztok!
Remélem jó topic-ban járok.
Szeretném megkérdezni, hogy egy készülő C++ programozási könyvsorozat számainak lektorlását vállalná-e valaki, amelynek első kötete már megjelent. Amennyiben valakit érdekel, kérem privátban jelezze. Ha rossz topikban járnék, akkor elnézést. -
szucs.miki
csendes tag
válasz
szucs.miki #2729 üzenetére
Nem tűnt ez olyan elvetemült ötletnek és eddig nagyjából működik is minden, még ha göröngyös is ez az út.
-
amargo
addikt
válasz
szucs.miki #2727 üzenetére
Sikerült kiválasztanod ezt az öszvér megoldást (.NET el kevert c++)? Megkérdezhetem, hogy miért?
-
amargo
addikt
válasz
szucs.miki #2725 üzenetére
mondjuk leirhatnad, milyen ablakkezelot használsz, bár azt gyanítom MFCt.
-
szucs.miki
csendes tag
Sziasztok!
A problémám a következő:
Visual Studioban írok egy windows applikációt C++ nyelven. Nem igazán vagyok otthon a témában, most csinálok először ilyet. Egy dialogbox-ot kellene létrehoznom. Addig jutottam, hogy resource-ként létrehoztam egy dialog-ot, amit tudok szerkeszteni meg mi egyéb. A kérdésem az lenne, hogy ezt a dialogot a form headerben hogy tudom példányosítani, elérni, megjeleníteni mondjuk egy gomb megnyomására?
A válaszokat előre is köszönöm! -
-
jattila48
aktív tag
válasz
EQMontoya #2721 üzenetére
Azért az újabb C++ 11 fordítóknak (pl. VS2012) tudtommal tudniuk kell. Főleg az unnamed RVO-t, ami szinte biztosan működik minden "normális" C++ fordítóval.
std::pair<int,int> swap(int x,y){
return std::pair<int,int>(y,x);
}Itt nincs a pair-ből temporális változó (ezért unnamed), ezért szinte biztos , hogy az RVO működik. Tehát körültekintő módon megírva a programot, nyugodtan számíthatsz az RVO-ra. Egyébként kis méretű visszatérő értékek esetén (pl. két int) akkor is a pair célszerűbb, ha netán nincs RVO. Vagyis tényleg ne féljetek a pair/tuple-től, a felvetett problémára szerintem ez a legelegánsabb C++ megoldás.
-
EQMontoya
veterán
válasz
jattila48 #2719 üzenetére
RVO-ra azért alapvetően nem bízzunk mindent (mondjuk egy chaininget - avagy avoid the void - simán), elvégre ahány compiler, annyi szokás. Főleg, hogy némelyik hajlamos hibás asm-et generálni, ha magasra veszed az optimalizációs flaget. (g++ 4.7 x86->arm crosscompilerekben láttam már több ilyen hibát is)
-
jattila48
aktív tag
válasz
pengécske #2715 üzenetére
Amit te akarsz csinálni, pontosan arra való az std::pair, illetve több visszatérő érték esetén az std::tuple. Ezek ugyan wrapper osztályok, de az STL-ben már készen kapod. Nem kell félni tőle, mert C++ 11-ben az RVO miatt nem kevésbé hatékony mint referenciaként vagy pointerrel átadott output paraméterekben (mint ahogy EQMontoya írta) visszakapni a kívánt értékeket, viszont sokkal átláthatóbb.
"így marad az, h stringbe kodolgatok": na ez az amit ne csinálj! Nagyon nem hatékony, sok hibalehetőséget rejtő, nagyon nem C++ szemléletű amatőr "megoldás".
Ursache: "Nekem még annyi jutott az eszembe, hogy Vector2D": ez tök jó, de mire is? -
pengécske
csendes tag
válasz
jattila48 #2714 üzenetére
Úgy értettem, h egy szám(adat)pár legyen a visszatérési érték. A complex szám csak egy példa volt, mert azokat ugy gondoltam, h a valós rész és a komplex rész egy-egy szám (tehát a+bi alak, ahol a és b a két adat amit tárolok). De akkor kösz, szoval nem képes rá
. Sokat könnyített volna, így marad az, h stringbe kodolgatok, vagy több külön függvényt hozk létre
-
jattila48
aktív tag
válasz
pengécske #2713 üzenetére
Nem pontosan értem a kérdésedet. Egy fv. pl. pair-ben adhat vissza két értéket (pl. két int-et), de C++ -ban ez igazából egy db. pair mint visszatérő érték. Ha komplex értéket ad vissza, az sem egy valós és egy képzetes rész float értékként, hanem egy komplex típusú érték, ahol a komplex osztályt te definiálod pl. valós és képzetes rész float típusú adattagokkal:
class komplex{
public:
....
private:
float valos,kepzetes;
};Ahhoz, hogy egy komplex számokat kezelő fv.-t valós számokra is lehessen alkalmazni (ez természetes elvárás), szükség van a valós számot komplex-re konvertáló fv.-re. Ez a komplex osztálynak egyetlen valós paramétert váró konstruktora lesz, amelyet szükség esetén (komplex értéket váró fv.-t valós paraméterrel hívsz) a C++ automatikusan meghív.
Tehát egy fv. egyetlen értéket képes visszaadni, azonban ez lehet alaptípus (int,char,float,...), vagy bármilyen osztály példánya (komplex) (vagy erre mutató pointer illetve hivatkozás). Ugyanolyan nevű fv.-ekből viszont lehet több, ha a szignatúrájuk (paraméter lista elemeinek típusa) különbözik. Ezek C++-ban teljesen különböző fv.-ek, és így különböző értékeket is adhatnak vissza (gondolom ezt tudod), azonban csupán a visszatérési értékük típusa szerint nem lehet így fv.-eket megkülönböztetni (bár a fv. prototípus ekkor is különbözőnek számít).
-
pengécske
csendes tag
Sziasztok!
Lenne egy kérdésem c++-ban (eléggé kezdő vagyok):
Hogyan lehetséges az, egy függvény több éréket adjon vissza? Például hogyha kiakarom bővíteni az alapműveleteket a complex számok körébe. Ezt hogyan lehetne megoldani?
Köszii a segítséget -
dabadab
titán
válasz
EQMontoya #2707 üzenetére
"Miert ne tenned?"
Mert a bennem élő egészséges lustaság arra késztet, hogy ne foglalkozzak az implementáció részleteivel, ha nem muszáj. Ha kell, akkor tudom, hogy ott a this is, de általában nem kell tudno, ill. amikor tanítják a C++-t, akkor azért problémás lehet ezt elővezetni, mert ez szinte az első dolog lehet(ne), ugyanakkor a megértéséhez szükséges az, hogy az ember értse, hogy hogyan is működnek a dolgok a CPU-ban, ami gyakran hiányzik a nebulókból.
-
wikings2
őstag
Sziasztok!
Lehet nem éppen témába vágó de azért súrolja az biztos:
Gra****oft cég éppen c++ területre keres diákot/kat, és nagyon szemezgetek a lehetőséggel, mint utolsó éves elte programozó informatikus palána. Abszolváltam már az alapismereteket, és a konkrét tárgyat is ahol főként iterátorosdi/stl tárolók-eljárások származtatások, templatek, és összefoglalva kb a stroustrup könyv lett átrágva és átadva nekünk. Igazából 1 csúszás miatt 3 tárgyam maradt vissza diplomáig, és szeretnék emellett már melózni ha lehet c++ irányban.
Kérdésem az lenne, hogy a cég "C++ programnyelv magasszintű ismerete" elvárását vajon mennyire fedheti a mostani tudásom? Olvastam más fórumokon, hogy az effective c++ könyv elég menő és sokat lehet belőle tanulni, de max átrágni lenne időm mivel nem szeretnék lemaradni semmiféleképpen sem a lehetőségről.
Ha valakinek vannak tapasztalatai vagy ötlete, bármit meghallgatok.
Köszönöm! -
jattila48
aktív tag
válasz
dabadab #2704 üzenetére
Lehet, hogy igazad van, és akkor hasznos külön felhívni a figyelmet a tfv.-ek constságára. Egyébként kár lenne, ha nem mondanák el, hogy a tfv.-ek első paramétere a this, és a név manglálás után semmiben sem különböznek a free függvényektől. Például nem gondolnának sokan olyat, hogy a tfv. bármilyen módon (pl. függvénypointer?) tárolva van az objektumban, mert ez nem igaz, és egy elég lényeges dolog (pl. az objektum mérete nem függ a tfv.-ek számától). Mellesleg az egész const mechanizmus jobban érthető, ha valaki tisztában van azzal, amit írtam (pl. nem const tfv.csak nem const objektumra hívható meg).
-
jattila48
aktív tag
válasz
dabadab #2702 üzenetére
A constság szerintem benne van a kérdező által írt szignatúrában, mivel ez a tagfüggvények első implicit this pointer paraméterére vonatkozik. Tehát nem const tfv. esetén ez a paraméter (a this pointer) T * const típusú, míg const tfv. esetén const T * típusú (T az osztály típusa), ami természetesen különböző szignatúrát jelent.
-
dabadab
titán
válasz
AsterixComic #2701 üzenetére
Maguk a kérdések is elég homályosak ill. konkrétan hibásak.
1. A parancssori paraméter (ahogy az a C++ standardban is van) csak char* típusú lehet (azok vannak az argv-ben). Az lehet, hogy egy karaktertömböt intként értelmezünk, de attól az még karaktertömb. Minden bizonnyal valami olyat akar hallani a tanár, hogy
int param=0;
if ( argc >= 2 )
{
param = atoi(argv[1]);
}2. Konstruktorra/destruktorra akkor van szükség, ha azt szeretné az ember, hogy az objektum létrejöttekor/megszűnésekor automatikusan lefusson valami kód. Az, hogy az a kód konkrétan mit csinál, tulajdonképpen lényegetelen. A dinamikusan foglalt memóriát máshogy is fel lehet szabadítani és egy csomó olyan esetben is szükség van *truktorra, amikor nincs dinamikusan foglalt memória (akár mindenféle lockokat meg nyitott handle-ket lekezelni, akár olyan egyszerű dolgok miatt, mint hogy az ember kiírjon vmi trace-t).
3. ...és a constsága, mert lehet két ugyanolyan nevű, azonos paraméterlistájú metódus, amik csak abban különböznek, hogy az egyik const, a másik meg nem.
-
AsterixComic
csendes tag
Sziasztok !
Egy kis segítséget kérnék szépen c++ programozáshoz kapcsolódóan.
Teljesen kezdő vagyok c++ programozás terén.Három kérdésben kérném szépen a segítségeteket, hogy mi lehet a pontos válasz rájuk.
1.) Adjon példát parancssori paraméterek elérésére. 1 int paraméter van a parancssorban.
Itt annyit tudok, hogy a main fgv. paraméterei közül az argc tartalmazza a parancssorban levő elemek számát. A char* argv[] -vel pedig hivatkozni tudunk rájuk.
Elég, ha feladatmegoldásként egy for ciklussal valahogy kiíratnánk azt az 1 int paramétert.2.) Mikor van feltétlenül szükség konstruktorra és destruktorra ?
Véleményem szerint destruktorra akkor van mindenképp szükség, ha dinamikusan foglaltunk le valamit a memóriában a new kulcsszóval és azt a destruktorban fel kell szabadítanunk.
Konstruktor esetében pedig egy default konstruktorra mindig szükség van, mert ha például úgy hozunk létre objektumot, hogy nem adunk meg minden paraméterének kezdeti értéket, akkor a default konstruktorban ezt le kell kezelnünk, hogy pl. pointer esetében NULL értéket ad, egész esetén pedig 0(nullát).3.) Mi határozza meg egyértelműen az eljárásokat meghíváskor ?
Véleményem szerint az eljárás neve és a paraméterek száma ÉS típusa határozza meg egyértelműen. Ugyanis tudtommal azonos nevű eljárásból sok lehet, de a hozzá tartozó paraméterlista csak egy lehet ugyanolyan.köszönöm szépen !
Új hozzászólás Aktív témák
Hirdetés
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- HiFi műszaki szemmel - sztereó hangrendszerek
- E-roller topik
- Apple asztali gépek
- Hobby elektronika
- AMD K6-III, és minden ami RETRO - Oldschool tuning
- bitpork: Augusztus 2- szombat jelen állás szerint.
- Tőzsde és gazdaság
- Vezetékes FEJhallgatók
- Milyen notebookot vegyek?
- Építő/felújító topik
- További aktív témák...
- AKCIÓ! HP ZBook Firefly 14 G9 üzleti notebook- i7 1255U 32GB RAM 512GB SSD nVidia T550 4GB Win11
- BESZÁMÍTÁS! MSI B450M R5 5500 16GB DDR4 512GB SSD RTX 2070 8GB Rampage SHIVA FSP 650W
- Wacom Cintiq DTK-2260 - Digitális rajztábla
- BESZÁMÍTÁS! ASRock H310CM i3 9100F 8GB DDR4 240GB SSD 1TB HDD GTX 1060 3GB AeroCool Strike-X 500W
- Dell Latitude 8-11. gen i5, i7, 2-in-1 szinte minden típus csalódásmentes, jó ár, garancia
Állásajánlatok
Cég: CAMERA-PRO Hungary Kft
Város: Budapest
Cég: PC Trade Systems Kft.
Város: Szeged