- Honor 200 Pro - mobilportré
- Szerkesztett és makrofotók mobillal
- Milyen okostelefont vegyek?
- Sony Xperia 1 V - kizárólag igényeseknek
- 65 órányi zenét ígér az Audio-Technica új TWS fülese
- Magisk
- Fotók, videók mobillal
- Yettel topik
- Samsung Galaxy Watch7 - kötelező kör
- Rendkívüli terméktámogatást ígér a Nothing
Új hozzászólás Aktív témák
-
jattila48
aktív tag
válasz
EQMontoya #3172 üzenetére
Azért, mert a példányosítandó template pimpl idiómát használ, ezért nem a header-ben vannak a tfv.-ek definíciói, hanem külön cpp fájlban. Egy másik cpp fájl szeretné használni a template egy osztálypéldányát, de a pimpl miatt csak a pimpl-es template-ből deklarál osztályt. A handler osztályt a template definíció helyén (a cpp fájlban) ezért explicit példányosítani kell.
-
jattila48
aktív tag
válasz
EQMontoya #3170 üzenetére
Köszi a választ! Ez lényegében ugyanaz, mint az én megoldásom, és a bajom is ugyanaz vele. A P tagfüggvényeit mind meg kell hívni (p.doSomething()
, ha azt akarjuk, hogy példányosuljanak. Valami olyasmit szeretnék, mint az explicit template példányosítás, de static_for-ban. Az explicit template példányosításkor nem kell meghívni a tfv.-eket, de mégis mind példányosulnak. Jó lenne, ha mondjuk egy sima template példány deklarálásakor ki lehetne kényszeríteni a tfv.-ek példányosulását is. Erre nincs mód?
A smiley ; és ) akart lenni. -
dobragab
addikt
válasz
EQMontoya #3112 üzenetére
Erős egyszerűsítés, szándékosan. Az eredmény végül is az, hogy a globális op new hívódik, és nem malloc. Tudod ellenőrizni, ha felüldefiniálod az op new-t.
#include <memory>
#include <vector>
#include <iostream>
#include <cstdlib>
void * operator new(size_t size)
{
std::cout << "op new!" << std::endl;
void * ptr = malloc(size);
if (ptr == nullptr)
throw std::bad_alloc();
return ptr;
}
int main()
{
std::vector<int> vec;
vec.push_back(1);
return 0;
}És ez a nullptr kivételével szabványos C++98.
-
dobragab
addikt
válasz
EQMontoya #3110 üzenetére
Akár egy struct-ot is lehet malloc-kal foglalni, és utána adattagonként inicializálni, bár jobb helyeken kétszeri lefejezés jár érte.
std::vector tudomásom szerint nem malloc-ot hív, hanem ::operator new-t. Ez a tény mondjuk C++ alapjai vizsgán erős.
Szóval kezdőknek: a fő különbség, hogy a new hívhat ctort a lefoglalt memóriaterületre, míg a malloc nem. Ha nem kell ctort hívni, simán helyettesítheti, de ez általában csak alaptípusnál fordul elő. Az részletkérdés, hogy kicsit máshogy kell használni, és más a hibajelzés módja.
-
jattila48
aktív tag
válasz
EQMontoya #3080 üzenetére
Azt hiszem, te ragaszkodsz egy koncepcióhoz, miszerint a különálló funkciókat külön osztályokban kell megvalósítani. Ez nálam is így van. Azonban létre kell hozni egy (és nem több) objektumot, ami ezeket a funkciókat egyben látja el. Tehát itt különbség van a funkciók implementálása (külön osztályokban), és azok használata között. A külön implementált funkciókat (a már említett okok miatt) egyben kell felhasználni. Erre én a származtatást használom, te pedig az egyébként máshol nem használt funkciókat unique_ptr-en keresztül "beinjektálod" a használt objektumba (ami innentől kezdve egyedül létezik, és szintén minden szükséges (egyébként külön implementált) funkciót ellát). Nálam egyik osztály sem tud önállóan létezni, csak a származtatás által összekapcsoltan, ahogy ez is a cél. Nálad a SourceReadFile ogjektum önállóan is tud létezni (sőt példányosítanod is kell), holott ennek semmi értelme, mert úgy is csak a másik osztályban tudod használni.
-
jattila48
aktív tag
válasz
EQMontoya #3080 üzenetére
Persze elég. Amit most példának írtam, abban is így van. Nem egészen erre gondoltam, rosszul fogalmaztam. Ettől függetlenül a fenit megállapításaimat fent tartom. Bonyolultabb, több hibalehetőséget magában rejtő megoldás, mint az enyém.
"Az a bajom az egybe pakolt megoldással, amiért nem is akar sézpen működni: teljesen különböző funkciókat szeretnénk bepakolni egy logikai csoportba."
A teljesen különböző funkciókat teljesen külön is választom: a blob feldolgozás az ősosztályba, a forrás kezelés/beolvasás a leszármazott osztályba. Persze amikor már példányosítom a leszármazott osztályt, akkor ezek a funkciók egy objektumban működnek, mint ahogy ez is a cél. (ld, ugyanaz a hatókör, a blob-ot vissza kell tudni írni, egységes RAII). A te megoldásodban sem fog külön önállóan létezni a SourceReadFile objektum (legalábbis nem sokáig, mert bele teszed egy unique_ptr-be), hanem rögtön "beinjektálod" a BlobProcess objektumba. Innentől kezdve, pedig ugyanúgy a BlobProcess objektum fogja ellátni az összes feladatot (blob feldolgozás, forrásba visszaírás). A SourceReadFile objektum önálló létének nincs is értelme, sőt a legjobb, ha minél előbb megszabadulunk tőle (RAII miatt), ezért legjobb, ha önállóan létre sem hozzuk. Persze a tényleg szükséges objektum leszármazott részeként marad.
Egyébként az "egybepakolt" megoldásom szépen működik. Miből gondolod, hogy nem akar? A te megoldásodat így gondoltad, ahogy a példában írtam? -
jattila48
aktív tag
válasz
EQMontoya #3078 üzenetére
Más a fájlból olvasás paraméterezése, más a registry olvasásé, más a resource olvasásé, más a hálózatról olvasásé, stb. De még ha lehetne is egységes read-et írni, akkor is nálad 3 osztály kell hozzá, amiből kettőt példányosítasz is, majd az elsőt "beinjektálod" shared_ptr-en keresztül a másodikba (hogy rendesen működjön a RAII), és tovább erre az objektumra a létrehozás helyén nincs is szükséged. Továbbá BlobProcess ctor-ában ugyanúgy meg KELL hívnod egy "külső" fv.-t, mint nálam az ősosztály init_blob-ját. Ráadásul nálam ez nem is annyira külső fv., hiszen az ős protected tfv.-e. És mivel a forrás, a blob számára lefoglalt memória és maga a BlobProcess objektum teljesen összetartozóak (ugyanakkor keletkeznek, ugyanaz az érvényességi körük, ugyanakkor kell megszűnniük), ezért tök fölösleges azon görcsölni (legalábbis szerintem), hogy szétválasszuk őket, aztán valahogy mégis csak egybe gyúrjuk (shared_ptr-rel). Erre sokkal természetesebb az én megoldásom. Azt hiszem ez is egy olyan eset, amikor nem biztos hogy vakon kell követni a "kőbe vésett szabályokat" (osztályt a ctor-a teljesen kell hogy inicializálni tudjon), persze érdemes tudni ezekről, de még fontosabb hogy az okát/értelmét ismerjük, és ha az adott feladatban ennek nem felel meg, akkor el lehet tekinteni tőle. Szerintem!
-
jattila48
aktív tag
válasz
EQMontoya #3075 üzenetére
Végül is tudná. Ahogy említettem, nem tudok minden forrásra egységes virtuális read_blob-ot írni. Egyébként erre gondoltál?
Az utolsó néhány sor így módosul:
class BlobProcess{
public:
BlobProcess(std::shared_ptr<SourceRead> sp):source_read_shared_ptr(sp){sp->read();process_blob(sp->get_blob_ptr(),sp->get_blob_length);}
private:
void process_blob(void *,DWORD);
std::shared_ptr<SourceRead> source_read_shared_ptr;
};
void main(){
auto source_read_file=std::make_shared<SourceReadFile>(new SourceReadFile("blob_file"));
BlobProcess blob_process(source_read_file);
} -
jattila48
aktív tag
válasz
EQMontoya #3073 üzenetére
"Amivel olvasol (legyen source), az legyen egy külön osztály, valami interface-szel. Ebből lehet leszarmaztatni sok félét"
Ezzel ugyan az a gond, mint az én megoldásomban. Az interface hogyan kapja meg a forrástól a blob-ot? A leszármazott osztály ctor-ának ugyanúgy meg kell hívni az intarface egy nem virtuális init_blob tfv.-ét, amivel ezt megteszi. Az interface-nek nem lehet a blob beolvasásra virtuális tfv.-e, mert a források különböző paraméterezést igényelnének erre (másrészt az interface ctor-ából nem szokás virtuális tfv.-t hívni). De ha lehetne is virtuális tfv.-e a forrás beolvasására, akkor is előbb létre kéne hozni az objektumot, majd meghívni rá a virtuális read-et (kétfázisú inicializálás). Gondolom az interface itt sem lenne példányosítható (hiszen ezért interface).
Valahogy így gondoltad?class SourceRead{
public:
SourceRead():blob_ptr(0),blob_length(0){}
bool read(){
return read_blob(&blob_ptr,&blob_length);
}
virtual ~SourceRead()=0{}
void * get_blob_ptr(){return blob_ptr;}
DWORD get_blob_length(){return blob_length;}
private:
virtual bool read_blob(void **blob_ptr,DWORD *blob_length)=0;
void *blob_ptr;
DWORD blob_length;
};
class SourceReadFile : public SourceRead{
public:
SourceReadFile(const std::string & source_name):source_name(source_name){}
~SourceReadFile(){/*megnyitott fajl lezarasa, allokalt memoria felszabaditasa*/}
private:
virtual bool read_blob(void **blob_ptr,DWORD *blob_length){
//source_name forras megnyitasa,beolvasando meret meghatarozasa, *blob_ptr=allokalt memoria cime,blob_length=merete
return true;
}
const std::string & source_name;
};
class BlobProcess{
public:
BlobProcess(std::shared_ptr<SourceRead> sp):source_read_shared_ptr(sp){process_blob(sp->get_blob_ptr(),sp->get_blob_length);}
private:
void process_blob(void *,DWORD);
std::shared_ptr<SourceRead> source_read_shared_ptr;
};
void main(){
auto source_read_file=std::make_shared<SourceReadFile>(new SourceReadFile("blob_file"));
source_read_file->read(); //ketfazisu inicializalas
BlobProcess blob_process(source_read_file);
}És itt már nem 2, hanem 3 osztály van, meg shared_ptr (tényleg! miért nem unique_ptr), amit nagyon nem szívesen használok. Ezzel szembem nálam 2 osztály van, amiből csak 1-et kell példányosítani, és nincs shared_ptr (sem_unique_ptr).
-
LordX
veterán
válasz
EQMontoya #3035 üzenetére
Lehet jó falura, de ugyanannyit kell írni (na jó, a függvény/osztálynevek hosszabbak), ha rendesen használsz <random>-ot.
Map: Nem értek egyet: mivel a map node-okban tárolja az adatot, amiben benne van a kulcs, az érték, és jellemzően 3 pointer (left, right, parent), ezért masszívan több memóriát foglal, mint a vector: Az összes általam ismert 64 bites implementációban 32 byte + sizeof(pair<K,V>) a node méret + allocation overhead. Win x64-en a sizeof 16 bye, tehát 40 byte a blokk, ahol az overhead átlagosan 56 byte (!!), azaz 96 byte. Per node. Ja, és a map-nek kell egy extra node (az end node). Szóval 10 elemhez kell 1056 byte heap memória map-el.
Vector esetében ez N*sizeof(int) + overhead, ami most 10*4+56 = 96, összesen a 10 elemre. 100 elemre ez 9696 vs 449 byte.
Szóval ha a cellák több, mint ~9%-át használod ki, akkor a vector nyer map ellen. És még nem is beszéltünk mennyire cache-friendly a vector, és mennyire cache-ellenséges a map; hogy a vektorban indexelsz, nem keresel.
Azért ha tényleg el kell tárolnod a kulcsot, egy kategóriával szebben áll a map, de még mindig vesztésre áll, nem véletlen van a flat_map a boost-ban (ami gyakorlatilag egy map interfész vector felett).
-
jattila48
aktív tag
-
jattila48
aktív tag
válasz
EQMontoya #3024 üzenetére
Részben igazad van, viszont az if feltételben megspóroltam egy tömb indexelést. Talán ez a megoldás hatékonyabb, és jobban átlátható. A gi-t sem kellett volna bevezetni, de ugyanezért lett az is. Nem tartozik ide, de szoktál assembly kódot debuggolni? Ott látszik, hogy egy tömb indexelés költségesebb mint egy sima változó elérés. Az értékadás pedig csak az if törzsében történik meg, ami feltehetően jóval ritkábban fut le, mint a feltétel kiértékelése.
-
jattila48
aktív tag
válasz
EQMontoya #3022 üzenetére
Nem szoktatom én sehogy, de hát a GURIT és TAR neveket nem én adtam, pedig szerintem magyarul vannak. Egyébként fogd fel úgy, hogy komment helyett adtam ilyen neveket. Vagy magyarul kommentezni is főbenjáró bűn?
"jobb helyen hirtelen felindulásból leggépuskáznak érte!" Ilyen helyekre én nem járok."A legkisebb dobás és a sorszámának külön eltárolása meg elég béna, ha egy egyszerű tömbindexeléssel elérhető hozzá az adat."
Ezt nem értem. Elmagyaráznád? -
jattila48
aktív tag
válasz
EQMontoya #3011 üzenetére
Nekem úgy tűnt, hogy a kérdező erre a konkrét feladatra volt kíváncsi, nem pedig az STL rejtelmeire. Szerintem ez számára nem könnyíti meg a dolgot. Annál is inkább, hogy alapvető dolgokkal van problémája (ld. case szerkezet), inkább ezekben kéne segíteni neki. Itt többen, többször elkövetitek azt a hibát (akinek nem inge ne vegye magára), hogy nem a kérdésre válaszoltok, hanem egyfajta összekacsintós bennfentes módon csillogtatjátok a magas szintű tudásotokat, ami a kérdezőnek ugyan nem segít, viszont fellengzőssé és lekezelővé teszi a hozzászólásotokat.
-
jattila48
aktív tag
válasz
EQMontoya #3008 üzenetére
"Erre való a map"
Hogyne! Mindjárt ágyúval verébre. Így lehet egy nagyon egyszerű, jó esetben pár száz byte-ra leforduló programból több megás lomha bloatware-t csinálni. Sajnos manapság tényleg ez a tendencia, és ez nem kis részben a "mindenre jó" template könyvtáraknak köszönhetö. Semmi funkcionalitású pimfli kis programok akkorák, hogy nem is olyan régen egy op. rendszer kisebb volt. Ide pl. nagyon nem kell a map a maga red-black tree megvalósításával, erősen túllövése a dolognak. -
MasterMark
titán
válasz
EQMontoya #2930 üzenetére
"pattintott C korszak" Hát ez nagyon nagy.
Én meg csak akkor tudnék igazságot tenni, ha egyáltalán tudnám, hogy miről beszéltek.
Ezért nem tudok hozzászólni. Soha nem hallottam se find-ot, se iterátor nem tudom mi, szóval.
jattila48: Breakkel nekem jó az már, bár ez a find érdekesnek tűnik. Igazából mint már írtam, azért kérdeztem, hogy While helyett for + break az jó-e. (Nem tudtam akkor még, hogy ennyi más lehetőség is van.
)
-
jattila48
aktív tag
válasz
EQMontoya #2930 üzenetére
Nem azt írtam, hogy lassú, hanem hogy lassabb. Pl. egy szövegszerkesztőnél ez lényeges szempont. Szövegszerkesztőt (marmint a szövegbuffert) nem írnék konténerekkel, iterátorokkal, standard és lambda függvényekkel (pl. szövegben egy sima find and replace az összes előfordulásra, hogy nézne ki nem "pattintott C" stílusban? Belegondolni is rossz). Szerintem szép számmal vannak olyan esetek, ahol a break nemhogy nem felesleges, hanem kifejezetten jobb megoldás, mint az elkerülésére tett C++ bűvészkedés. Ha lehet, én is elkerülöm, pl. a ciklusfeltételbe való beépítéssel.
-
válasz
EQMontoya #2907 üzenetére
Ezt most talaltam nalunk (nem C++, de a lenyeg atjon):
/**
* A utility class to create the objects
*/
public class ObjectUtil {
private ObjectUtil() {
}
public static Activity getActivity(Person author,Person target) {
Activity activity = new Activity();
activity.setAuthor(author);
activity.setTarget(target);
return activity;
}
}Looks like a fckin' constructor to me
-
dobragab
addikt
válasz
EQMontoya #2905 üzenetére
Rosszabb. ZH-ban láttam.
int emelet(int szobaszam)
{
switch(szobaszam / 100)
{
case 0: return 0; break;
case 1: return 1; break;
case 2: return 2; break;
case 3: return 3; break;
case 4: return 4; break;
case 5: return 5; break;
case 6: return 6; break;
case 7: return 7; break;
}
return -1;
} -
dobragab
addikt
válasz
EQMontoya #2901 üzenetére
Pontosan ugyanebbe futottam bele Linux Mint-en, 4.8-as GCC. Arch-on 5.2-es GCC mellett írtunk egy makefile-t, ami gond nélkül megette. Utána Minten próbáltam fordítani, a linker undefined reference miatt halt el szinte minden linkelendő függvénynél. Szerencsére hallottam már a problémáról, röpke 10 perc alatt rájöttem.
-
LordX
veterán
válasz
EQMontoya #2897 üzenetére
Ez talán a link order hülyeség lesz. Nem ignorálja a paraméteredet, hanem hülyén működik a linker: a paraméterek sorrendjében megy végig a linkelendő objektumokon (.cpp esetében forditás után), és belinkeli a {main függvényt, namespace static objektumokat, eddigiek által referált függvényeket}. Szóval a .cpp-ben hiába referálsz a protobuf függvényére, linker nem találja meg, mert nem találkozik vele a cpp után.
Én is falra tudok mászni ettől..
-
LordX
veterán
válasz
EQMontoya #2870 üzenetére
Nem, mellékhatással rendelkező konstruktor is áldozatul eshet a copy elisionnek:
[class.copy] bekezdés (jó hosszú alfejezet, a vége felé):
"When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects."
(A "certain criteria" az (N)RVO, a "hagyományos" copy elision és a throw ill catch esetében az exception objektumok konstrukciója listát tartalmazza.)
-
jattila48
aktív tag
válasz
EQMontoya #2870 üzenetére
A T s=T(); deklarációban nincs copy elision (és másfajta optimalizáció sem), mert nincs rá szükség, ha triviális a copy ctor, ha nem. Egyszerűen a T() ctor hívódik meg és hozza létre az s-et mindenféle optimalizációtól függetlenül.
"Ha mondjuk van ott egy logolás, akkor simán le fog futni a default ctr majd a copy"
Mármint a copy ctor-ban van logolás? Nem fog lefutni, és a log sem fog kiíródni, és ez nem az optimalizáció miatt van, hanem mert deklarációban ez egyszerűen így működik. Próbáld ki! Mellesleg copy elision esetén (itt nem aróól van szó!) akkor is kioptimalizálhatja a copy ctor hívást, ha van megfigyelhető mellékhatása (ol. logolás). Ez is benne van a szabványban. -
ToMmY_hun
senior tag
válasz
EQMontoya #2866 üzenetére
Először is köszi a választ! Azért szeretném ezt használni, mert lenne egy osztályom amiben egy szerver socketet szeretnék futtatni és a socketet új threadben akarom indítani. Az új threadet az osztály konstruktorában indítom és ugye ott kéne neki átadni a futtatandó metódust is, ezért lenne szükségem a pointerre. Az osztálynak csak a socket által kiküldött vektor feltöltése és magának a socket kommunikációnak a lebonyolítása a feladata, egy példány lesz belőle. Ha erre lenne valami szebb megoldási javaslat, akkor annak örülnék és köszönöm előre is! Addig is kipróbálom amit javasoltál.
Static metódus ugye azért nem frankó, mert akkor nem érem el az osztály belső változóit. Persze ha úgyis csak egy példány lesz, akkor lehet singleton és úgy el is érem, de nem tűnik szimpatikusnak a megoldás, tuti van ennél szebb.
-
jattila48
aktív tag
válasz
EQMontoya #2847 üzenetére
Az assert valóban nem véd alul indexelés ellen, nem akartam annyit írni. Ez amúgy is csak egy vázlat. Megoldható úgy is ahogy írod, de szerintem így elegánsabb (és talán hatékonyabb). Amúgy nem sok eset van, amikor a const_cast-nak létjogosultsága van, ez az egyik (más most nem is jut eszembe), ezt is szerettem volna bemutatni. Ha teljesen kidolgoznám a példát, akkor pl. a scalar_type-ot is megnézném, hogy triviálisan másolható-e, és ettől függően írnék vagy nem írnék hozzá copy ctort és értékadó operátort. Esetleg a default ctort lenne érdemes átalakítani, hogy az összes elemet adott értékkel feltöltse (ekkor persze már nem default) pl. így:
explicit my_matrix(T x=T()){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]=x;
}
}
} -
jattila48
aktív tag
válasz
EQMontoya #2845 üzenetére
Valóban, az operator+ tagoperator helyesen my_matrix operator+(const my_matrix &mm) const
operator* tagoperator pedig nincs. const_cast azért kell, mert a nem const verzió ugyanaz mint a const verzió, csak nem const objektum egy elemére ad vissza nem const referenciát. Itt most egyszerűbb lett volna beírni ugyanúgy azt az egy sort, azonban ha const verzió változik, változtatni kell a nem const verziót is. Bonyolultabb esetekben is általában ez a megfelelő megoldás. A const_cast-ok csak a fordítónak szólnak, nem generálódik kód hozzá, így aztán hatékony is. -
LordX
veterán
válasz
EQMontoya #2838 üzenetére
struct X {};
struct Y {
Y() = default;
Y(X) {}
Y operator +(const Y& right) { return *this; }
};
Y operator *(const Y& left, const Y& right) { return left; }
void f() {
X x1, x2;
Y y1, y2;
auto t1 = x1 + y1; //member op - nem fordul le
auto t2 = y2 + x2; //member op - lefordul
auto t3 = x1 * y1; //free op - lefordul
auto t4 = y2 * x2; //free op - lefordul
} -
LordX
veterán
válasz
EQMontoya #2835 üzenetére
Erősen ellenjavallott kétoperandusú operátoroknál a tagfüggvényes megvalósítás, ha létezik implicit konverzió más típusokról. Eléggé hülyén néznek a userek, ha a*b lefordul, b*a nem. (Jó, most a mátrixszorzásnál ez nem annyira számít, mert amúgy is csak a megfelelő mérteket kell hagyni.) Ha lehetséges, legyen az operátor szabad függvény, és legyen friend, ha belső dolgokban is turkál.
-
#99472384
törölt tag
válasz
EQMontoya #2814 üzenetére
Üdv.
Tévedsz, nem maradt ki az utánaolvasás, de nem is ezzel van a gond, mert nagyvonalakban értem.
A fordítással van a gond, mivel nincs Visual C++ -om, ami meg ingyenes, az nem fordítja le, de nem is csoda mert szinte önmagával sem kompatibilis.Hogy milyen operációs rendszerre kell, azt leírtam. 32 vagy 64 bit szinte tökmindegy, mert 64bites Athlonom van, és az op rendszerből is van 32 és 64 bites verzióm. Persze a 32bites verzió lenne a jobb megoldás. Az meg hogy mit és hogyan számol, az tökmindegy, és nincs egyszerűbb megoldás, ugyanis amit számolnia kell az eleve nem publikus.
Ezt a programot is azért írta egy német fickó, mert az egyik ilyen fájlja megsérült, és használhatatlanná vált.No, de ezek jelenleg lényegtelen információk.
Amit linkeltél, az eddig is világos volt számomra, de mint írtam nem is ez a gond.
-
yossarian14
tag
válasz
EQMontoya #2801 üzenetére
Így írtam be, de elszállt a program, nem fut le. Gondolom valamit rossz helyre tettem.
void process(string fileName) {
cout << ++j << ": " << fileName << endl;
ifstream file(fileName);
string line;
const int size = 10*1024*1024;
char mybuffer [size];
file.rdbuf()->pubsetbuf(mybuffer,size);
while (getline(file, line))
{
}
} -
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!
-
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?
-
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.
-
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?
-
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))
-
jattila48
aktív tag
-
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.
-
-
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.
-
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.
-
EQMontoya
veterán
válasz
EQMontoya #2695 üzenetére
Válaszolva erre is: ma már eléggé nagy multi lett, keresnek kezdőt, tapasztaltat, javast, pythonost, PM-et, stb.
C++-os vonalon igazából nem kell semmilyen ilyen múlt, akinek van tapasztalata és vágja a c++, vagy kezdő de van jó agya és affinitása, azt felveszik simán.Lassan 700 fő a cég, szegedi irodával, nincs már olyan nagy válogatás... Azért mondjuk az Ericssonnál, NSN-nél magasabban van a mérce még mindig.
-
zsambek
aktív tag
válasz
EQMontoya #2682 üzenetére
Haha
Ha mar itt tartunk, most neztem, hogy meg biztosan le van mentve a 2003-as evfolyamig a felhasznalo fiokok, szoval nem tudom, h mikor vegezted az infot, de esetleg meg te is be tudnal lepniValósítson meg C++ nyelven egy olyan osztályt (F12),
amely egyrészt átadható a 2. feladat megoldását segítő
függvénynek (solveF2(const F2&)), másrész képes az STL deque
sablonjához hasonlóan működve ASCII karaktereket tárolni!
C++ nyelven a többszörös öröklést célszerű használni, ha
egy objektumnak többféle interfésszel kell rendelkeznie, ezért
a feladat megoldásához előkészített f12.h állományban, mely
az aktuális katalógusban (...) található,
az F12 osztályt az F2 és a Queue osztályból származtattuk.
Az F2-ben deklaráltuk azt az f() függvényt, ami a hftest 2. feladatát
hivatott megoldani. A Queue osztály pedig egy karaktereket tároló
kétvégű sort valósít meg az STL deque sablonjának felhasználásával,
de attól egy kicsit eltérő funkcionalitással.
Az Ön feladata megvalósítani az f12.cc állományban az F2,
az F12 és a Queue osztály tagfüggvényeit és statikus adattagjait.
Az F2 osztály double f(double) tagfüggvénye a következő függvényt
kell, hogy megvalósítsa (ld. 2. feladat):
f(X) = X/120.90, ha X > 35,
f(X) = 0.472*X^4 - 0.943*X^3 + 60.38*X^2 + 3*X - 35, ha X <= 35
A Queue osztálynak van egy myIteraror nevű iterátora is,
amellyel a karaktersorozat az elejétől a végéig bejárható.
Segitségképpen egyes tagfüggvényeket már definiáltunk az f12.h
állományban.
Figyelje meg, hogy az iterator milyen egyszerűvé teszi a tároló
kezelését! Az f12_main.cc állományban lát erre példát, ami az aktuális
(...) katalógusban található a fordítást segítő
f12.mak állománnyal együtt.
Ha elkészült, fordítsa le, ill. tesztelje az osztályt
a következő paranccsal:
make -f f12.mak
A make lefordítja az f12.cc-t valamint az
f12_main.cc-t és így futtatható a keletkező f12 nevű program.
Az f12_main.cc a teszetlést segíti. Azt igénye szerint módosíthatja.
Az f12.h állományt azonban NE módosítsa!
Ha úgy gondolja, hogy helyesen oldotta meg a feladatot, akkor a
make -f f12.mak submit
paranccsal adja be azt az automatikus feladatellenőrző rendszernek.
Az automatikus teszt csak az f12.cc állományban megvalósított
F2, F12 és Queue osztályok működését vizsgálja, azaz, hogy megfelelnek-e
a fent megadott specifikációnak. Így nem veszi figyelembe az f12_main.cc
tartalmát, és azt sem, ha esetleg módosított az f12.h-ban! -
Jester01
veterán
válasz
EQMontoya #2643 üzenetére
Minden bizonnyal olyan környezetben vagy ahol az int és a double között van egy kis üres hely. Például ha az int 32 bites a double meg 64 akkor lesz közöttük 4 byte üres hely. Az ip++ erre az üres helyre fog mutatni, viszont a dp már félig át fog lógni a double tagba.
Ú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!
- Makulátlan PlayStation 5 lemezes kiadás + 2 játékkal, garanciával!
- AMD Ryzen 7 7700 - Új, 1 év garancia - Eladó!
- AMD Ryzen 7 5700X - Új, 3 év garancia - Eladó!
- Dell G3 3500 Gamer laptop szép állapotban dobozával. (i7 10750h, Gtx 1660ti, 16GB ram, 1TB ssd)
- Asus F15 FX516PR 15.6" FHD IPS i7-11370H RTX 3070 16GB 1TB NVMe magyar vbill gar
- BESZÁMÍTÁS! MSI Z390 i5 9400F 16GB DDR4 512GB SSD RTX 2060Super 8GB Corsair Carbide Series 200R 600W
- AKCIÓ! Lenovo Legion Slim 5 Gamer notebook - R7 7435HS 16GB RAM 1TB SSD RTX 4070 8GB GDDR6 WIN11
- Lenovo ThinkPad 40AF docking station (DisplayLink)
- Kingmax 1x2GB DDR3-1333 RAM
- AKCIÓ! Apple Macbook Pro 16" 2019 i9 9980HK 64GB DDR4 1TB SSD Radeon Pro 5500M garanciával
Állásajánlatok
Cég: Promenade Publishing House Kft.
Város: Budapest
Cég: PC Trade Systems Kft.
Város: Szeged