Offset segitsegevel struct elemei kezelese

Címkék
Offset segitsegevel struct elemei kezelese
2022-02-13T17:31:21+01:00
2022-02-15T11:43:57+01:00
2022-10-15T21:20:35+02:00
*deleted_71586391
Hello,

A kovetkezo kod segitsegevel kulonbozo struct elemek kapnak erteket. A problema az, hogy ha van egy struct ami tartalmaz egy vectort egy intern deklaralt structbol akkor ha ez egyik struct elem kap erteket akkor a vector tobbi struct eleme is atveszi azt az erteket es nem marad optional.

Pl: Struct S 

   int s;
   struct S1 
   {
      boost::optional<int> x;
   };
   std::vector<S1> vS1;


- Ha van peldaul 3 eleme a vS1-nek es az elso elemnek a x-je kap erteket a masik ketto nem marad boost::none hanem ok is atveszik az elso erteket, ha peldaul a masodiknak van erteke akkor a harmadik atveszi a masodik elemeinek az erteket.

A kovetkezok hivodnak: 
InternalClassReflector::setValue
InternalClassHolder::setValue
ClassReflector::setValue
FieldReflector::setValue
Mutasd a teljes hozzászólást!
Csatolt állomány
Nem tudom miert lett ilyen bonyolult modon implementalva,  de ezen nem valtoztathatunk.

Pedig ahogy nézem, legalább a Ref.hpp-hez hozzá kell nyúlnod. Most már nagyjából felfogtam, hogy van egy privát mező, ahol fel lehet építeni egy listaelemet, aztán annak a mezőnek a tartalmát lehet hozzáadni a listához egy hívással. Két hozzáadás között nem reseteli a privát mezőt, szóval amit nem írsz felül az úgy marad, ahogy az előző hozzáadásnál volt.

Ha feltehetjük, hogy a listaelemeknek van default konstruktoruk és minden hozzáadás után alapállapotba lehet hozni a privát mezőt, akkor meg lehet próbálni ezt beszúrni a Ref.hpp 301. sora után:

*internalObj = FieldType();
Mutasd a teljes hozzászólást!

  • Nem tudom, hányan akarnak majd négyszáz sornyi kódban hibát keresni. Szerintem jobban járnál ha minimalizálnád a problémát: kivennél minden kódot ami nem szükséges a probléma előidézéséhez, és csak azt hagynád meg ami feltétlen szükséges. Eközben lehet hogy te is rájönnél a hibára, de ha mégsem, akkor is jobb esélyed van, hogy valaki hajlandó legyen felfogni és hibát keresni benne.
    Mutasd a teljes hozzászólást!
  • Koszonom a visszajelzest, barmi eszrevetel jol johet!
    Mutasd a teljes hozzászólást!
  • Nekem eddig jut a fordítás:

    $ clang -c KissLaszlo.cc -o KissLaszlo.o KissLaszlo.cc:3:5: error: unknown type name 'CLASS_REGISTER' CLASS_REGISTER(PtpStatusData) ^ KissLaszlo.cc:3:34: error: expected ';' at end of declaration list CLASS_REGISTER(PtpStatusData)
    A g++ tovább jut:

    $ g++ -c KissLaszlo.cc -o KissLaszlo.o KissLaszlo.cc:21:10: fatal error: boost/optional.hpp: No such file or directory 21 | #include <boost/optional.hpp> | ^~~~~~~~~~~~~~~~~~~~
    A boost-ról már hallottam, hogy azoknak való, akiknek a C++ önmagában túl kicsi és átlátható, de most csak ezért nem szeretném telepíteni.
    Mutasd a teljes hozzászólást!
  • Koszonom, sajnos nem tudok olyan koddal szolgalni ahol nincs hasznalva a boost optional
    Mutasd a teljes hozzászólást!
  • Egyrészt ez, másrészt meg amit beidéztél, az nem is egy program, csak különféle header-file-ok részletei vagy ilyesmi.
    Mutasd a teljes hozzászólást!
  • Hello, sikerult rekonstrualnom a problemat: Compiler Explorer - C++ 
    Barmilyen segitseget elore is nagyon koszonok!

    FieldType* interalObj = ((FieldType *)(((unsigned char *)&obj) + reflector.fieldOffset())); std::vector<FieldType>* collectionObj = (std::vector<FieldType> *)(((unsigned char *)&obj) + collectionReflector.fieldOffset()); collectionObj->push_back(*interalObj);
    Az source elemek hozzaadasa a vektorba az alabbi koddal tortenik, de ekkor mar az elemek megkaptak az ertekeiket, szoval itt nem lehetne az interalObj-t initializalni.



    Oszinten megmondom, hogy nincs otletem mikepp lehetne ezen valtoztatni es azt elerni, hogy teljesen uj elemet rakjunk a vektorba es ne az elozo masolatat
    Mutasd a teljes hozzászólást!
  • Az segítene, ha elárulnád az egész dolog hátterét. Gondolom van valami indok mögötte, hogy miért ilyen többszörösen elvont, sztringeket használó módon kell beállítani az objektumot, nem pedig közvetlenül elérve a mezőket. Esetleg valami szkriptnyelvvel kell integrálni a C++ kódot, és annak a nyelvnek van szüksége a név szerinti elérésre?

    Simán lehet, hogy nem a mostani kódot kéne megjavítani, hanem hátrébblépni és más megközelítésből megoldani a problémát.

    (Vagy ha minden kötél szakad, akkor nem lehetne az optional mezőket kézzel resetelni, mielőtt új elemet adsz a listához?)
    Mutasd a teljes hozzászólást!
  • <ptp-status> <reporting-period>8</reporting-period> <lock-state>LOCKED</lock-state> <sources> <local-port-number>1</local-port-number> </sources> <sources> <local-port-number>2</local-port-number> <time-source>2</time-source> <priority1>2</priority1> </sources> <sources> <local-port-number>3</local-port-number> <time-source>2</time-source> <priority1>4</priority1> </sources> </ptp-status>

    Ehhez hasonlo  rpc-reply parsingolasanal hasznaljuk ezt a modszert.
    Nem tudom miert lett ilyen bonyolult modon implementalva,  de ezen nem valtoztathatunk.
    Nincs kulonosebb ok ami miatt csak igy lehetne ezt csinalni. A libyang api-val megkapjuk a mezoket, pontosan tudjuk, hogy milyen tipusu, listabol van, stb es ezzel a modszerrel egy adott objektum megkapja az erteket
    Mutasd a teljes hozzászólást!
  • Nem tudom miert lett ilyen bonyolult modon implementalva,  de ezen nem valtoztathatunk.

    Pedig ahogy nézem, legalább a Ref.hpp-hez hozzá kell nyúlnod. Most már nagyjából felfogtam, hogy van egy privát mező, ahol fel lehet építeni egy listaelemet, aztán annak a mezőnek a tartalmát lehet hozzáadni a listához egy hívással. Két hozzáadás között nem reseteli a privát mezőt, szóval amit nem írsz felül az úgy marad, ahogy az előző hozzáadásnál volt.

    Ha feltehetjük, hogy a listaelemeknek van default konstruktoruk és minden hozzáadás után alapállapotba lehet hozni a privát mezőt, akkor meg lehet próbálni ezt beszúrni a Ref.hpp 301. sora után:

    *internalObj = FieldType();
    Mutasd a teljes hozzászólást!
  • Koszonom, sajnos igy nem mukodik: Compiler Explorer - C++ mivel minden mezot none-ra tesz.

    Az otletet ertem de peldaul a masodik elemnel ha mar elozoleg 2 setelve van es egy harmadik kap erteket akkor az elso kettot kellene none-ra rakni, ezzel a modszerrel honnan tudna, hogy az elso kettot resetelni kell ?

    valoszinuleg valahogy meglehetne azt csinalni, hogy minden fieldName-et lementunk (setFieldNames) ami erteket kapott es listaba szuras elott a struct osszes elemet ami nem szerepel a setFieldNames-be es optional resetelni. 
    vagy meglehetne azt oldani, hogy ne masolatat hasznaljunk hanem egy uj elemet ?
    Mutasd a teljes hozzászólást!
  • Légy szíves olvass figyelmesebben. Azt írtam, a 301. sor után kéne beszúrni.
    Mutasd a teljes hozzászólást!
  • Nagyon szepen koszon, oszinten. Ugy tunik, hogy mukodik.
    Ha meg annyit kerhetek, hogy roviden elmagyarazd, hogy pontosan miert is mukodik igy.
    Mutasd a teljes hozzászólást!
  • Ahogy fentebb írtam, van egy struct típusú privát mező, ami a listaelemek "előkészítéséért" felelős. Ennek a mezőnek a mezőit lehet állítgatni a setValue hívásokkal, aztán a setCollectionValue a mezőt hozzáadja a lista végére.

    A változtatásom annyit csinál, hogy a setCollectionValue, miután hozzáadta a privát mező tartalmát a listához, felülírja a mező tartalmát egy frissen létrehozott, ugyanolyan típusú változó tartalmával. Ezzel effektíve alapállapotba hozza az adattagokat.

    Ha nagyon pontosak akarunk lenni, abban az egy sorban három dolog történik egymás után:
    1. A "FieldType()" kifejezés létrehoz egy átmeneti változót, és inicializálja az alapértelmezett konstruktorával.
    2. A FieldType = operátorát meghívva átmásolja az átmeneti változó tartalmát a privát mezőbe. (= operátort írhatsz magadnak is, de ha nem írsz, a fordító alapesetben ír neked egyet.)
    3. Felszabadítja az első lépésben létrejött átmeneti változót.

    Ez valamivel kevésbé hatékony, mintha közvetlenül állítanád alaphelyzetbe a mezőket, de a célnak meg kell hogy feleljen.
    Mutasd a teljes hozzászólást!
  • Biztos, hogy ezt akartad kimenetnek?

    ptpSData1.reporting_period: 17 p.sources.size(): 3 s.local_port_number: 0 s.priority1 not SET s.local_port_number: 0 s.priority1 not SET s.local_port_number: 0 s.priority1 not SET

    Persze csak te tudhatod, hogy mit akartál, de szerintem sokkal inkább a push_back után akartad reset-elni az elemeket és nem előtte.
    Mutasd a teljes hozzászólást!
  • igy igaz, a push_back utani resettel mukodik es az felel meg az ahitott kimenetelnek.
    Mutasd a teljes hozzászólást!
  • igy igaz, a push_back utani reset-el mukodik es felel meg az ahitott kimenetelnek:
    Pl:

    ptpSData1.reporting_period: 17 p.sources.size(): 3 s.local_port_number: 10 s.priority1 not SET s.priority2 not SET s.local_port_number: 0 s.priority1 SET: 12 s.priority2 not SET s.local_port_number: 8 s.priority1 not SET s.priority2 SET: 13
    Mutasd a teljes hozzászólást!
Címkék
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd