C++ kérdések

Kezdőlap Fórumok Programozás C++ kérdések

10 bejegyzés megtekintése - 31-40 / 120
  • Szerző
    Bejegyzés
  • #2023698
    pointux
    Felhasználó

      „Hát nemtudom… A tapasztalataim azt mutatják, hogy elég nemdeterminisztikusan mûködtek a dolgok… Azaz volt, hogy a kritikus sor elõtti kiiratás volt ok, néha az utána lévõ is megjelent, vagy a 10 sorral alattuk lévõ is… „
      Ez könnyen elõfordulhat, bár az esetek többségében hasznos a kiíratás…
      Minden bizonnyal azért „nemdeterminisztikus”, mert statikus a hiba pl:
      A fent említett „” hiba.
      Adott egy memóriaterület (M), ahova a karakterfolyam beíródik (chs):
      M: „”
      chs: „ABC”
      Történetesen ekkor semmi gond nincs. De mi van, ha a programot újra lefuttatod és a paraméterek:
      M: „jnefgjh”
      chs: „ABC”
      Semmi nem változott, csak a program egy másik „nem kinullázott” memória területet használ a „chs”-hez. Ellenben a program teljesen kiszámíthatatlanul fog viselkedni. (Ez az eset pedig könnyen elõfordulhat.)

      Természetesen vannak olyan programok melyek ezeknek a jó részét ki tudják szûrni. (Mármint azt mondják, hogy ez, meg az nem biztonságos… Minden bizonnyal erre is azt mondják, bár nyílván, ha „” a vége, akkor – a teljes átgondolás igénye nélkül – elvileg nem lehet gond… bár nyílván az ellenõrzõ program nem tudhatja. :))

      Sõt egy másik („semmi köze”) függvényben is keletkezhet kár, ha nem vigyáz az ember. Jó megoldás erre egy „céltalan” mutató. Vagy az amikor van egy túl kicsi adatterület, meg egy utána jövõ (szabadon írható) másik függvény adat, vagy – ne adj isten – futtatható terület. (Hogy mit hova fog tenni a fordító, azt ugye nem biztos, hogy lehet tudni… azt meg, hogy a rendszer hova foglal memóriát pláne nem. Szerencsére ez utóbbiból adódó komoly hibák lehetõsége a „biztonságos nyelvek/fordítok” esetében ritka, hiszen a szegmensek elkülönülten, jól meghatározott rwx móddal érhetõek el, csak annak és csak úgy, ahogy szabad.) Ne ebben az esetben – fel kell kötni azt a bizonyost – hiszen elõfordulhat, hogy „A”-ban van a hiba és a tökéletes „B” hibázik (ne adj isten – következetesen) miatta. 🙂

      A kiíratást egyébként a lehetõ legjobb a legegyszerûbb és legbiztonságosabb eszközökkel elvégezni.

      #2023699
      roante
      Felhasználó
        kl223 wrote:
        class SzuloOsztaly {
            public:
                virtual void kiir() { std::cout < < "SzuloOsztaly!"; }
        };

        class GyermekOsztaly : public SzuloOsztaly {
            public:
                virtual void kiir() { std::cout < < "GyermekOsztaly!"; }
        };

        Ekkor:

        GyermekOsztaly a;
        SzuloOsztaly b = a;
        b.kiir();

        Kimenete „Gyermekosztaly!” lesz, hiába hogy egy „SzuloOsztaly” típusú objektumról van szó egyébként.
        Azzal a nem-felüldefiniálható cuccal meg majd még kísérletezek, hátha sikerül vmit elérnem. Ha igen, írom majd.

        kl223

        Hmmm…. Ennenk elvileg le sem szabadna fordulnia, nem? Mármint arra gondolok, hogy nem is biztos, hogy a két objektum mérete azonos! Pl. ha ez lenne:

        class GyermekOsztaly : public SzuloOsztaly {
            public:
                virtual void kiir() { std::cout < < "GyermekOsztaly!"; }
                int i;
        };

        akkor a GyermekOsztály pontosan sizeof(int)-el nagyobb, mint a SzuloOsztaly. Amúgy nekem a kimenete „SzuloOsztaly” lett…
        Az más tészta, hogy ha

        GyermekOsztaly a;
        SzuloOsztaly &b = a;

        van, mert akkor már egy létezõ memóriaterületre akasztok egy másik nevet, és ez „GyermekOsztaly!”-t ír ki, a dinamikus kötésnek köszönhetõen.
        Ugyanígy, ha pointerekkel csinálod:

            GyermekOsztaly *a = new GyermekOsztaly();
            SzuloOsztaly *b = a;

        Akkoris a „GyermekOsztály!” íródik ki.

        #2023700
        roante
        Felhasználó

          Azon gondolkoztam, hogy lehet, hogy ezzel kapcsolatban hülyeséget mondtam:

          GyermekOsztaly a;
          SzuloOsztaly b = a;

          Asszem ilyenkor a cpp nekiáll copykonstruktort keresni, de az nincs. Aztán nekiáll értékadó operátort keresni, de az sincs. Mivel egyik sincs, ezért gondolom castolgat egyet, az viszont menni fog, és ezért nem áll neki átmásolgatni a az adatokat, mint a C, és ezért nem gáz a méret, ezért nem fagy szét rögtön segfault-al.

          Az egész csak hipotézis, nem nagyon vágom a cpp-t, még csak most tanulgatom.  :blush:

          #2023701
          pointux
          Felhasználó

            Van értelme csak ebben az esetben egy kicsit fura…
            A eset:

            Code:
            class ClassP {
                public:
                    ClassP () {)
                    virtual void write () {}
            };

            class ClassC {
                public:
                    ClassC () {)
                    virtual void write () {}
            };

            ClassC CC; – CC::CC lefutása
            ClassP CP = CC; – (ClassC)CC bemásolása (ClassP)CP-be, ami egyértelmûen konverciós hiba

            B eset

            Code:
            B/1:
            class ClassP {
                public:
                    ClassP () {)
                    virtual void write () {}
            };

            class ClassC {
                public:
                    ClassC () {)
                    virtual void write () {}
            };

            ClassC CC; – CC::CC lefutása
            ClassP CP = (ClassP&)CC – CP inicializálása CC:CC-ral (tehát CP::CP nem fut le!!!, viszont az objektum létezik)
            ClassP.write() – mivel nem CC.write-ra, hanem CP.write-ra mutat, az fut le
            (Két dolog miatt jöhet létre: a c-ben a jobb oldalon lévõ mûvelet – mely elõször fut le – és érték is)

            B/2
            class ClassP {
                public:
                    ClassP () {)
                    virtual void write () {}
            };

            class ClassC : public ClassP{
                public:
                    ClassC () {)
                    virtual void write () {}
            };

            ClassC CC; – CP::CP lefutása CC::CC lefutása
            ClassP CP = CC – CP inicializálása CP:CP-ral (mivel már CP::CP elõzõleg lefutott; konvertálás sem kell, mert CC, mindent örököl)
            ClassP.write() – eredmény ugyanaz

            Tehát igazad van, a ClassP write függvénye fog lefutni… más nem is futhat le.

            C eset:

            Code:
            ClassC *CC = new ClassC();
            ClassP *CP = CC;
            CP->write();
            Esetén más a helyzet, hiszen CP egyenesen CC-re mutat, tehát a ClassC write virtual függvénye hívódik meg
            #2023702
            FLINX
            Felhasználó
              #2023703
              FLINX
              Felhasználó

                Ja megpróbálom csatolni a teljes forrást hátha sikerül…

                #2023704
                aty
                Felhasználó

                  Nem csináltam soha, de az egyik oldali objektum nem az aktuális objektum éppen? Tehát elég lenne egy argumentum is, nem? Következésképp akkor nem is friend függvények.

                  #2023705
                  FLINX
                  Felhasználó
                    aty wrote:
                    Nem csináltam soha, de az egyik oldali objektum nem az aktuális objektum éppen? Tehát elég lenne egy argumentum is, nem? Következésképp akkor nem is friend függvények.
                    #2023706
                    pointux
                    Felhasználó

                      Kétféleképpen lehet operátort deklarálni:
                      1)

                      Code:
                      class Class {
                          Ret operatorX ( Param )
                      }
                      Class::operatorX…

                      Ennek megfelelõen, vagy Ret-nek, vagy Param-nak az osztálynak kell lennie, annak megfelelõen, hogy… (Mindkettõ is lehet)

                      2)

                      Code:
                      class Class {
                      friend … az ott leírt mód
                      }

                      Az (1) esetben az osztály (egy) konstruktora és a paraméter között van a mûveletvégzés. A (2) esetben a két paraméter között… figyelembe véve, hogy jobbérték, az a kiértékelése, majd a visszatérési érték alapján annak a mûveletvégzése a balértéken. Na most itt a gond! Van egy „endless”-ed az kiértékelõdik lesz egy „int” típusod a jobb oldalon a bal oldal viszont !!!soha!!! nem vár „int” típust! Valahogy így nézne ki:
                      bal_endless ( ( int ) jobb_endless ( ) ) – neked ilyened nincs (ezt kell létrehozni, olyan bal_endless-t mely képes e fogadására)
                      (Hogy mi a mûvelet nem lényeges, mert azt a függvény maga végzi.)

                      #2023707
                      pointux
                      Felhasználó

                        Ahol egyébként nem változik meg az érték, mint jelen esetben ==, < stb. tagfüggvényként javaslom deklarálásra, egyébként a visszatérésként pedig az objektumok címének megadását, mert ugye, ahogy említettem a jobb oldal visszatérési értéke a bal oldal paramétereként beíródik... innentõl nem kell magyarázni. 🙂

                      10 bejegyzés megtekintése - 31-40 / 120
                      • Be kell jelentkezni a hozzászóláshoz.