- Milyen processzort vegyek?
- Alapértelmezett konfiguráción sok Core CPU-nak lehet stabilitási gondja
- NVIDIA GeForce RTX 3080 / 3090 / Ti (GA102)
- Modern monitorokra köthető 3dfx Voodoo kártya a fészerből
- Intel Core i5 / i7 / i9 "Alder Lake-Raptor Lake/Refresh" (LGA1700)
- Furcsa EPYC CPU-kkal készül az AMD
- Házimozi haladó szinten
- Androidos tablet topic
- Hobby elektronika
- TCL LCD és LED TV-k
Hirdetés
-
Toyota Corolla Touring Sport 2.0 teszt és az autóipar
lo Némi autóipari kitekintés után egy középkategóriás autót mutatok be, ami az észszerűség műhelyében készül.
-
Kipróbáltuk az LG kompakt 4K projektorát, a CineBeam Q-t
ph A szokatlan külsejű, kisméretű vetítő webOS okosrendszert is kapott.
-
Végre megjelenési dátumot kapott az xDefiant
gp Az érdeklődők már május második felében belevethetik magukat a harcokba.
Új hozzászólás Aktív témák
-
doc
nagyúr
válasz Ereshkigal #3303 üzenetére
azokkal meg nem talalkoztam, milyen velemenyeket hallani roluk?
-
ToMmY_hun
senior tag
Tegyük fel, hogy placement new-val foglalsz területet egy objektumnak és ebből készítesz pointert, vagy készítesz egy szimpla változót, és azt éred el cím alapján. Szerinted ez egy és ugyanaz? Lehet C++-szal kezdeni, de nehéz menet lesz. Szerintem egyszerűbb az alapokkal kezdeni, majd abból építkezni magasabb szintek felé. Nálunk a suliban ASM volt a kezdés, utána C, aztán opcionálisan C++ vagy egyéb. Szerintem így eléggé alaposan el lehet sajátítani a szükséges szemléletmódot és tudást. Nem véletlenül oktatják ilyen sorrendben az egyetemeken sem.
C programmers never die, they are just cast into void.
-
doc
nagyúr
válasz ToMmY_hun #3305 üzenetére
mert C++-ban NEM lehet olyat hogy "készítesz egy szimpla változót, és azt éred el cím alapján", ugye?
az egyetem meg megint mas kerdes, szerintem nem azert iratkozik be valaki egyetemre hogy megtanulhasson (5+ ev alatt) C++-ban programozni. Ott teljesen mas a cel, igy nyilvan mas a bejarando ut is.
-
jattila48
aktív tag
Hogy az eredeti kérdésedre válaszoljak:
Stanley Lippmann: C++ primer
van magyar kiadása is (nem a legújabb) C++ először címmel. Szerintem egész jó könyv kezdőknek. Utána pedig természetesem a Sroustrup könyv. Az internetem is rengeteg könyvet/cikket találsz pl. Scott Meyers effective c++, vagy Herb Shutter GotW cikkei. A DrDobbs folyóirat cikkei kifejezetten jók C++ témakörben (meg másban is).
Egyébként mivel a C gyakorlatilag része a C++-nak, nincs értelme azon vitázni, hogy a kettő közül melyiket tanuld meg. A C-t meg tudod tanulni anélkül, hogy C++-t tanulnál, de fordítva nem. Ha C++-t tanulsz, akkor meg fogod tanulni a C-t is. És it most nem az a lényeg, hogy nem printf-fel iratsz ki. Értelmetlen azon vitázni, hogy a pointerek használatát C-ben vagy C++-ban sajátítod el, mert ez egy és ugyanaz. Referenciák meg nincsenek a C-ben. Aki nem ismeri alaposan a C nyelvet, az a C++-t sem ismeri. Kezdőknek pedig nem OOP szemléletet és STL-t kell tanítani, hanem írja meg C-ben az alap algoritmusokat (keresés, rendezés, stb), értse meg a paraméterátadás rejtelmeit (érték, cím,...), írjon rekurzív fv. hívást, stb. Ez később mind hasznára fog válni, amikor már a C++ esetleg magasabb szintű absztrakcióit használja. Pontosabban enélkül, soha nem lesz belőle jó C++ programozó. Akkor jön az, hogy mindenre (a legegyszerűbb dolgokra is) kész STL tárolókat/algoritmusokat és könyvtárakat keres, mert nem érti elég mélyen a problémát (hiszen soha nem ásott bele amúgy "pattintott" C megközelítéssel), és azt sem látja át, hogy a készen kapott megoldások nem feltétlenül alkalmazhatók az ő problémájára. Na ekkor jön a patkolás: az eszközhöz igazítja a feladatot, és nem fordítva. A C++ és az OOP csak eszköz, és ha "pattintott" C megközelítéssel egy feladata átláthatóbban, hatékonyabban oldható meg, akkor úgy kell megoldani. Nincs ebben semmiféle ellentmondás. A struktúrált és az OOP megközelítés nem zárják ki egymást, egyik sem szentírás. Az osztályod tfv.-eit legalábbis igyekszel struktúrált módon megírni (C-ben az sem szentségtörés ha nem), még ha az adatszerkezet OOP megközelítésű is. A virtuális tfv.-ek mibenlétét, működési módját, használatát sem igazán lehet megérteni anélkül, hogy C-ben soha nem írtál fv. pointereket tartalmazó tömböt. Nem szaporítom tovább a szót, a lényeg, hogy teljesen felesleges és mesterséges a C és C++ nyelvek szembeállítása, mivel nem két külön nyelvről van szó.„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár
-
jattila48
aktív tag
válasz ToMmY_hun #3305 üzenetére
Bocs, hogy kijavítalak: placement new-val nem foglalsz területet, hanem már lefoglalt területen (pl. malloc-cal, de lehet stack-en is) létrehozod az objektumot. Gyakorlatilag a ctor. "közvetlen" hívására használják, ami azért kerülendő (bár néha szükséges).
„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár
-
dobragab
addikt
válasz jattila48 #3307 üzenetére
Kezdőknek pedig nem OOP szemléletet és STL-t kell tanítani, hanem írja meg C-ben az alap algoritmusokat (keresés, rendezés, stb), értse meg a paraméterátadás rejtelmeit (érték, cím,...), írjon rekurzív fv. hívást, stb. Ez később mind hasznára fog válni, amikor már a C++ esetleg magasabb szintű absztrakcióit használja. Pontosabban enélkül, soha nem lesz belőle jó C++ programozó.
Tökéletesen egyetértek.
Igazából lényegtelen, hogy C vagy C++ a nyelv, de C++-ban egy csomó olyan dolog van, aminek dependency-je, hogy értse, hogyan van C-ben.
Például amíg nem tudja _tökéletesen_, mi az a pointer, nem kéne sem referenciát, sem okos pointert tanulni. Sőt, okos pointereket csak azután kéne, hogy megvolt az OOP, a RAII, a template és esetleg a jobbérték referencia.
Amíg nem érti tökéletesen, mi az a tömb, hogy a méretét nem tudja lekérdezni függvényből, hogy mi köze a pointerhez, stb. addig nem szabad neki std::vectort tanítani, mert utána már sosem tanulja meg, mi is az a tömb.
std::string-et is csak azután kéne tanítani, hogy érti a tömböket, használta a karaktertömböket, stb.
Fvptr -> öröklés ugyanez.
Szóval sorolhatnám még a dependency-ket, de nem sok értelme van. Az a lényeg, hogy ezeket be kell tartani, és bizony C-ben nem lehet ezt a szabályt megszegni, mert nincsenek ilyen cuccok. C++-ban sokkal könnyebb "rossz útra tévedni", míg C-ben nem lehet. Ha betartja ezeket a játékszabályokat, akkor a C++ jobb lehet, mert egy csomó f*szságot meg tud úszni a scanf-től a qsort-ig, de jóval nehezebb ezeket betartani.
Tudom, tudom, akasszak a tökömre egy lámpát, hogy sötétben is tudjak kaszálni.
-
dabadab
titán
válasz dobragab #3313 üzenetére
"Amíg nem érti tökéletesen, mi az a tömb, hogy a méretét nem tudja lekérdezni függvényből, hogy mi köze a pointerhez, stb. addig nem szabad neki std::vectort tanítani, mert utána már sosem tanulja meg, mi is az a tömb."
Ez abszolút nem igaz. Én is megtanultam, pedig BASIC tömbökkel kezdtem, amik sokkal több rokonságot mutatnak az std::vectorral, mint a C-s tömbökkel.
Valahol el kell kezdeni a tanulást és nem lehet rögtön kettes számrendszerrel meg mutatókkal kezdeni, mert hiányoznak az alapok ahhoz, hogy meg tudják érteni, hogy mi az. Meg én is előbb használtam virtuális függvényt, minthogy tudtam volna, hogy mi az a vtable, aztán mégis ember lettem
DRM is theft
-
ToMmY_hun
senior tag
Sziasztok!
Viszonylag régóta küzdök egy probléma megoldásával, és eddig nem jöttem rá önerőből, hogy mivel lehet a gond.
Adott egy class, aminek nincs default constructor-a, csak paraméterezett. A gondom az, hogy ezt szeretném egy std::pair-be rakni. Az alábbi szintaktikát használva fordul a kód, viszont futás közben memóriaszemét lesz a pair second elemében.
pair<string, ArmPart> p("test", ArmPart(1, "name", 2, 3));
Valaki meg tudná mondani, hogy mi ennek az oka? Annyit fűznék még hozzá, hogy az ArmPart osztály a Part osztály leszármazottja, és a Part paraméterezett konstruktorát hívja meg init list-ről.
Köszönöm előre is a választ.
[ Szerkesztve ]
C programmers never die, they are just cast into void.
-
dobragab
addikt
-
EQMontoya
veterán
-
dobragab
addikt
válasz EQMontoya #3321 üzenetére
Konkrétan C++98-ban:
- default ctor: végighívja az ősosztályok és adattagok default ctor-át, sorrendben. Ha írsz bármilyen ctort, ami nem copy ctor, bukod a default ctort, kézzel kell írnod, ha akarsz. (vagy = default, C++11-ben)
- copy ctor: végighívja az ősosztályok és adattagok copy ctor-át, sorrendben.
- operator=: végighívja az ősosztályok és adattagok operator=-jét, sorrendben.
- dtor: végighívja az adattagok és ősosztályok dtor-át, ebben a sorrendben- címképző operátor (&)
- vessző operátor (,)Ehhez hozzá jön a C++11-es move ctor és move assignment operator, ami ha kínai, nézz utána alaposan a jobbérték referenciáknak.
- move ctor: a move ctor-okat hívja végig, ha van, egyébként a copy ctort
- move op=: a move op=-ket hívja végig, ha van, egyébként a sima op=-tEz a kettő csak akkor van, ha
- nincs a felhasználó által írt copy ctor vagy dtor,
- nincs a felhasználó által írt másoló vagy move operator=,
- nincsen valami miatt implicit törölve (például mert az egyik adattagé törölve van).Mindennek az a célja, hogy az erőforráskezelést el tudd rejteni egy-egy erre specializált osztály belsejébe, pl. string vagy vector. Ezeket aztán máshol úgy tudod használni, mint egy sima int-et, mert a fordító mindig tudja, mikor mit kell meghívni. A felsőbb szintű (nem erőforráskezelő) osztályoknak nem kell foglalkoznia a fent említett tagfüggvényekkel, a default is úgy fog működni, ahogy elvárjuk.
Nyilván ez nagyon le van egyszerűsítve, de nagyságrendileg stimmel.
Jávához képest: van destruktor, mégpedig arra, hogy bármilyen erőforrást (memória, fájl, mutex, grafikus memória, stb.) becsukjon. Ha jól tervezed meg az osztályaidat, ezek mind automatikusan történnek. A GC ennél butább, mert csak memóriát szabad / lehet rábízni.
Jó, igen a finalize-ra elvileg rá lehet bízni pl. egy fájl bezárását, de az ki tudja, mikor fut le... Nagyon nem vicces nyitva hagyni egy fájlt random ideig, amíg a GC össze nem szedi a memóriában lévő objektumot. Ezért van jávában minden fájlkezelős történet try - catch - finally blokkban, hogy akármi történik, kézzel be tudd csukni a fájlt. C++-ban a compiler biztosan becsukja a fájlt a blokk végén (fstream).
Kicsit elkanyarodtam a kérdéstől. Remélem, azért mondtam újat, rosszat meg nem
[ Szerkesztve ]
Tudom, tudom, akasszak a tökömre egy lámpát, hogy sötétben is tudjak kaszálni.
-
ToMmY_hun
senior tag
válasz dobragab #3322 üzenetére
Nagyon szépen köszönöm a részletes leírást! Nekem sok újat mondtál és gyors összefoglalónak kiváló - legalábbis így kezdőként könnyen fel tudtam fogni. A biztonság kedvéért a mester könyvében lévő konstruálással foglalkozó fejezetet tervezem átnyálazni, bár sok információt a cppreference.com-on is leírnak.
Java-hoz képest jóval bonyolultabb a konstruálás (is), de nagyon szimpatikus az a precizitás, amit a nyelv megkövetel. Kivéve amikor ilyen apróság miatt megy el pár óra.
EQMontoya: "Elég fontos dolog, ha mélyebben belemész a c++-ba." Teljesen jogos, meg is van a programom estére.
[ Szerkesztve ]
C programmers never die, they are just cast into void.
-
jattila48
aktív tag
válasz dobragab #3322 üzenetére
Jó összefoglaló, csak egy kis kiegészítést engedj meg:
"- default ctor: végighívja az ősosztályok és adattagok copy ctor-át, sorrendben."
Itt fontos megjegyezni, hogy az ősosztályok ctorát az öröklési sorrendben, az adattagokét pedig deklarációjuk sorrendjében hívja. Vagyis nem feltétlenül a taginicializáló listában írt sorrendben (néhány fordító warning-ot generál, ha a taginicializáló lista sorrendje eltér a deklaráció sorrendjétől). Ezek után hajtódik végre a szóban forgó objektum ctorának törzse. A destruktorok hívása éppen fordított sorrendben történik: Először az adott dtor törzse fut le, ami végül a ctor-ok hívásának fordított sorrendjében meghívja az adattagok és ősosztályok dtorait.A move operációt illetően: a szabvány bizonyos feltételek mellett (kb. amit leírtál) előírja implicit move operáció generálását, azonban erősen kétséges, hogy ez valóban jó ötlet-e. Bizonyos fordítók (talán a VS2010 is) ezt nem teszik. Ha egyáltalán generálható implicit move operáció, akkor az kb. ugyanaz mint a copy operáció, ezért fölösleges a move. A move-nak akkor van igazán értelme, amikor implicite nem generálható, pl. user defined dtor esetén. A move-val legfőbb probléma az, hogy milyen állapotban maradjon a moved-from objektum, vagyis az operáció forrás objektuma. Legyen default konstruált? Mi van, ha nincs default ctor-a? Az "elmove-olt" erőforrást a dtor-nak már nem szabad felszabadítania. A moved-from objektum egyfajta "zombivá" válik, hasonlóan a kétfázisú inicializálással létrehozott objektum esetén, amikor a ctor már lefutott, de az inicializálás még nem történt meg teljes egészében (ez mint tudjuk, kerülendő). A moved-from objektum ezután már csak copy vagy move assignment cél operandusaként használható, vagy megsemmisítendő, de minden esetre ügyelni kell rá, hogy ne használjuk újra (mint ahogy a félig inizializált objektumokat sem).
„Kétségtelen, hogy nem tudjuk, mit tegyünk, de felkészültek és elszántak vagyunk.” - Olaf Scholz német kancellár
-
dobragab
addikt
válasz jattila48 #3325 üzenetére
Vagyis nem feltétlenül a taginicializáló listában írt sorrendben (néhány fordító warning-ot generál, ha a taginicializáló lista sorrendje eltér a deklaráció sorrendjétől). Ezek után hajtódik végre a szóban forgó objektum ctorának törzse.
Pontosan. Mivel az inicializáló listát már ismeri, feltételeztem, ezzel is tisztában van.
Normális fordítóktól kapsz ilyenkor warning-ot, különben _nagyon_ könnyű hibás kódot írni.
class String
{
char * data;
size_t size;
public:
String(char* d, size_t s) :
size(s),
data(new char[size+1])
{
// ...
}
// ...
};Első ránézésre nem is látszik, miért hibás a kód, ha a fordítótól nem kapsz warningot, órákig keresheted.
Ha egyáltalán generálható implicit move operáció, akkor az kb. ugyanaz mint a copy operáció, ezért fölösleges a move.
Háát... nem. Ha az Example osztálynak adattagja egy std::vector, marhára nem mindegy, hogy az Example-nek generál-e move ctort, vagy nem. Ha generál, a vector is move-olódni fog, míg ha nem, másolódik (ahol beleszólhat a copy elision, de ezt most hagyjuk).
[ Szerkesztve ]
Tudom, tudom, akasszak a tökömre egy lámpát, hogy sötétben is tudjak kaszálni.
-
kobe24
tag
Sziasztok!
Most tanulom a c++ programozást egyetemen, viszont van egy dolog amit nem igazán értek. Lehet-e egy programon belül struktúrát és osztályt is használni? Vagy ha az egyiket használom, akkor nincs szükség a másikra? Nem nagyon értettem meg az órán, viszont mintha megmaradt volna egy olyan mondat, hogy az osztályon belül is lehet létrehozni struktúrához hasonló dolgot, bár lehet csak összekeverem valamivel. Kellene csinálnom egy otthoni feladatot, azzal nincs is bajom, hogy megcsináljam, de csak úgy sikerült, hogy van benne struktúra is és osztály is. A válaszokat előre is köszönöm! -
EQMontoya
veterán
Igazából két különbség van az osztály és a struktúra között, de az is lényegében csak egy:
-Stuktúrában public a default láthatóság, classban private.
-Szemléletbeli: struktúra már C-ben is volt, igaz, sokkal limitáltabb funkciókkal, nem tudott osztályként működni. C++-ban mindent tud, amit az osztályok, a fentebbi minimális különbséggel. Ennek ellenére alapvetően classokat használunk, leginkább a szemlélet okán. Vannak esetek, amikor szokás struktúrát, ez alapvetően az, amikor csak egy kupac adatot szeretnénk egybe kezelni (pl. egy függvény adna vissza öt különböző dolgot, akkor annak nyilván nem öt referencia paramétere lesz, hanem valahogy összepakoljuk a dolgot), és nincsennek a dolognak tagfügvényei, illetve nem szeretnénk belőle elrejteni semmit. Igen, ez kb. az, amire C-ben is használtuk a structokat, erre nyugodtan lehet C++-ban is.Mint látod, az egész inkább konvenció, mint gyakorlati különbség.
Same rules apply!
-
doc
nagyúr
Persze, a ketto nem zarja ki egymast. Az adott feladattol/helyzettol fugg hogy melyik a jobb/kenyelmesebb megoldas.
Apro megjegyzes (ne zavarjon ossze): C++ -ban a struct es a class az szinte teljesen ugyanaz, igazabol csak a default lathatosag mas
MOD: most latom hogy elkestem, mindegy, mar itt marad
[ Szerkesztve ]
-
kobe24
tag
Köszönöm mindkettőtöknek a választ! Így már érthetőbb, és közben meg is tudtam csinálni struktúra nélkül a feladatot. Még az az egy kérdésem lenne, hogy az osztályon belül definiáltam egy string pointert, majd később mikor már szeretném felhasználni ezt a változót, megadom neki, hogy y=new string[db], viszont ha így próbálom elindítani a programot, akkor egyből lefagy, és be kell zárni, de ha a db helyére egy konkrét számot írok, esetemben 400-at, akkor hiba nélkül lefut a program. Én próbálgattam keresni, hogy mitől lehet ez, de sokra nem jutottam. Az biztos nem lehet, hogy túl nagy lesz a tömb, mert a db változó nem lehet nagyobb mint 400.
-
kobe24
tag
[link]
A db változót int tömböknél elfogadja, csak a stringnél van valamiért gondja. Szóval ha azt a 400-at átállítom db-ra, akkor egyből kifagy, semmi nem fut le a programból. Biztos én csinálok valamit rosszul, de nem tudok rájönni mi az. -
dobragab
addikt
Ilyen esetben nem gáz struktúrát használni, sőt, azt kellene. Ez így elég ronda. Valahogy így érdemes:
class Merkozes
{
public:
int fordulo;
int hazaigol;
int idegengol;
int hazaifelidogol;
int idegenfelidogol;
string hazaicsapat;
string vendegcsapat;
};
std::istream& operator>>(std::istream& be, Merkozes& M)
{
Merkozes result;
be >> result.fordulo;
be >> result.hazaigol;
be >> result.idegengol;
be >> result.hazaifelidogol;
be >> result.idegenfelidogol;
// nem biztos, hogy kell, de
// int után string-et beolvasni nem mindig egyszerű
be >> std::ws;
be >> result.hazaicsapat;
be >> result.vendegcsapat;
}
class Merkozesek {
private:
std::vector<Merkozes> adatok;
public:
Merkozesek();
~Merkozesek();
void Kiir();
void Gyoztes();
void Nev();
void Statisztika();
};
Merkozesek::Merkozesek(){
ifstream be("eredmenyek.txt");
if (be.fail()) {
cerr << "hiba";
system("pause"); // jáj, mér?
exit(1);
}
Merkozes M;
while (be >> M)
adatok.push_back(M);
}Így már nem szivárog (ömlik) a memória.
[ Szerkesztve ]
Tudom, tudom, akasszak a tökömre egy lámpát, hogy sötétben is tudjak kaszálni.
-
kobe24
tag
válasz dobragab #3338 üzenetére
Köszönöm ismét a segítséget!
Ezzel a megoldással amúgy csak annyi a problémám, hogy a második résznél azt se értem mi történik. Biztos ez a legegyszerűbb módja, de egy minimális magyarázatot kaphatok, mert érteni is szeretném a programomat, de ez egyelőre csak összekavar. -
EQMontoya
veterán
#include <iostream>
class A
{
public:
A() : m_i(0) { }
protected:
int m_i;
};
class B
{
public:
B() : m_d(0.0) { }
protected:
double m_d;
};
class C
: public A
, public B
{
public:
C() : m_c('a') { }
private:
char m_c;
};
int main()
{
C c;
A *pa = &c;
B *pb = &c;
const int x = (pa == &c) ? 1 : 2;
const int y = (pb == &c) ? 3 : 4;
const int z = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb)) ? 5 : 6;
std::cout << x << y << z << std::endl;
return 0;
}Aki futtatás nélkül helyesen mondja, hogy mit ír ki (és hogy miért), az előtt emelem kalapom.
Be kell valljam, nekem is le kellett futtatni 1x, hogy megértem, mi történt.Same rules apply!
-
EQMontoya
veterán
-
dobragab
addikt
válasz EQMontoya #3347 üzenetére
Megspékelem két sorral.
Először:
const int t = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(&c)) ? 7 : 8;
Utána C-be kerüljön egy virtuális destruktor, a feladat ugyanez!
virtual ~C() {}
Tudom, tudom, akasszak a tökömre egy lámpát, hogy sötétben is tudjak kaszálni.
-
EQMontoya
veterán
válasz dobragab #3348 üzenetére
Amivel nem csinálsz semmit, mert nem kerül bele a coutba!
Egyébként az első sor önmagában nyilván nem csinál semmit, elvégre a C elején az A rész van.
A virtuális desktruktorral (és bármi egyéb virtuális függvénnyel ugyanúgy) viszont behozol egy vptr-t a class elejére, tehát az elején már nem A lesz.[ Szerkesztve ]
Same rules apply!
-
dobragab
addikt
Új hozzászólás Aktív témák
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- Milyen processzort vegyek?
- gban: Ingyen kellene, de tegnapra
- Alapértelmezett konfiguráción sok Core CPU-nak lehet stabilitási gondja
- Yettel topik
- Ubiquiti hálózati eszközök
- bambano: Bambanő háza tája
- Vodafone mobilszolgáltatások
- Android szakmai topik
- Aliexpress tapasztalatok
- Külpolitika
- További aktív témák...
- Eredeti Samsung Galaxy A72 doboz, töltő, adatkábel, papírok, Sim tű (Foxpost az árban!!)
- Alkatrésznek való Asus X705 17,3 laptop / működik
- Apple Watch 6, Midnight, 44mm, Gps+Cellular ( eSim ) független, 85% akku
- Apple IPad 9th Gen 64GB Wifi+LTE Állapot: 10/10 Akku:100%
- 2x8 GB Samsung DDR3 12800 eladó