.[ ČeskéHry.cz ].
C++: implicitne konstruktory a destruktory...

 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
niXon



Založen: 27. 10. 2007
Příspěvky: 22

PříspěvekZaslal: 6. duben 2008, 20:25:23    Předmět: C++: implicitne konstruktory a destruktory... Odpovědět s citátem

tak zdravim, mam taky maly problem, postupne si skusam priklady z Mistrovstvi v C++ , akurat som na praci s triedami a mam tu taky maly problem... podla toho co som sa docital by malo fungovat nasledovne:

kód:
#include <iostream>

class string
{
public:
    char *data;
    int len;

public:
    string() {
        len = 0;
        data = new char[len+1];
        data[len] = (char)0; // klasicky nulovy znak na konci
    }

    string(const char *str) {
        len = std::strlen(str);
        data = new char[len+1];
        std::strcpy(data,str);
    }

    ~string() { delete [] data; }
};

int main() {
     string r;
     r = "Skuska";

     return EXIT_SUCCESS;
}


no, trosicku som si to debugoval (jednoducho pomocou vypisou a COUT), zistil som kde je asi zadrhel, ale neviem ako ho riesit...

spustaju sa dva konstruktory, prvy krat , pri 'string r' a druhy krat 'r = "Skuska"' to je logicke... v poriadku, ale problem je, ze sa dva krat spusta aj destruktor, co ale uz logicke nieje (teda podla poctu konstruktorov ano, ale nemozeme dva krat mazat ten isty objekt no nie?) ako to mam riesit? pretoze spustenie dvoch destruktorov mi vyvolava crash programu koli snahe dva krat mazat pole data. dakujem
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
(CZ)genius



Založen: 28. 07. 2007
Příspěvky: 85
Bydliště: Neratovice

PříspěvekZaslal: 6. duben 2008, 20:47:49    Předmět: Odpovědět s citátem

no já do tohodle zas tolik nevidim, ale rek bych, ze nejdriv se zavola konstruktor pro r. pak se zavola konstruktor pro string("Skuska"), ale ta je jenom docasna.. vytvori se, nastavi dylka atp., priradi se do r a pak se znici (tim se zinvalidni i pointery v r). a pak se nici r, ktere uz mas spatne pointery..
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Quiark



Založen: 29. 07. 2007
Příspěvky: 816
Bydliště: Chlívek 401

PříspěvekZaslal: 6. duben 2008, 21:08:52    Předmět: Odpovědět s citátem

Jo, jde o to, že při r = "Skuska" se děje toto:

  1. Vytvoří se třída string z "Skuska"
  2. Zkopíruje se pomocí operator = (který vytvořil překladač, protože ty ho tam nemáš) ze objektu "Skuska" do objektu r.
  3. Smaže se objekt "Skuska" a v r zůstane neplatný pointer.

_________________
Mám strach


Naposledy upravil Quiark dne 6. duben 2008, 22:39:02, celkově upraveno 1 krát
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 6. duben 2008, 21:27:15    Předmět: Odpovědět s citátem

jj jak rika Quiark - chvili mi to sice trvalo - ale je to tak - chybi kopirovaci konstruktor a ten jednoduchy co vytvori kompiler jenom tupe zkopiruje hodnotu pointeru
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
MePHyst0



Založen: 28. 07. 2007
Příspěvky: 85
Bydliště: SVK/CZK

PříspěvekZaslal: 6. duben 2008, 21:27:37    Předmět: Odpovědět s citátem

este aby som spravil quiarkovu odpoved kompletnu, musis teda pretazit operator== resp copy constructor

EDIT: beaten by rezna
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Quiark



Založen: 29. 07. 2007
Příspěvky: 816
Bydliště: Chlívek 401

PříspěvekZaslal: 6. duben 2008, 21:33:55    Předmět: Odpovědět s citátem

V tomto případě je potřeba hlavně operator =, pokud se nepletu. Copy constructor se volá jen při vytváření objektu, tedy
kód:

string r("Skuska");
případně
string r = "Skuska";


EDIT: Opraveno z == na =.
_________________
Mám strach
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 7. duben 2008, 00:14:06    Předmět: Odpovědět s citátem

Copy constructor je pěkná svině a volá si i při předávání hodnotou. Wink Nebo když máte nějaký jiný objekt, který předáváte hodnotou, tak i jeho členské proměnné volají kopírovací konstruktor (pokud ho nenapíšete u původní třídy). Je lepší tedy vždy implementovat oba způsoby kopírování.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
niXon



Založen: 27. 10. 2007
Příspěvky: 22

PříspěvekZaslal: 7. duben 2008, 12:18:29    Předmět: Odpovědět s citátem

dakujem vam vsetkym za rady, tak ako ste povedali, stacilo si spravne nadefinovat operator=() ... tu je funkcny vysledok:

kód:
#include <iostream>

class string
{
public:
   char *data;
   int len;

public:
   string() {
      len = 0;
      data = new char[len+1];
      data[len] = (char)0; // klasicky nulovy znak na konci
   }

   string(const char *str) {
      len = std::strlen(str);
      data = new char[len+1];
      std::strcpy(data,str);
   }

   ~string() { delete [] data; }
   
   string &operator=(const string &str) {
      delete [] data;
      len = str.len;
      data = new char[len+1];
      std::strcpy(data,str.data);

      return *this;
   }
   
   string &operator<<(const string &str) {
      int nLen = len + str.len;

      char *nData = new char[nLen];
      char *nData2 = nData;

      std::strcpy(nData,data);
      nData2 += len;
      std::strcpy(nData2,str.data);

      delete [] data;

      len = nLen;
      data = nData;
      
      return *this;
   }
};

int main() {
   string a,b,c;
   a = "Skuska ";
   b = "retazca.";
   c << a << b << " A druha skuska.";
   
   std::cout << c.data << "\n";

   return EXIT_SUCCESS;
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 7. duben 2008, 12:28:15    Předmět: Odpovědět s citátem

mno kdyz uz jsme u toho

kód:
public:
    char* data;
    int len;


tak takhle fakt ne Wink - o zapouzdreni tu probehla uz spousta diskuzi a je to dobre si ho uvedomit a zacit pouzivat drive nez ziskas spatne navyky
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Augi



Založen: 28. 07. 2007
Příspěvky: 782
Bydliště: Čerčany

PříspěvekZaslal: 7. duben 2008, 13:46:35    Předmět: Odpovědět s citátem

Imho evidentně překlep, protože tam má 2x nad sebou "public:" Wink
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
niXon



Založen: 27. 10. 2007
Příspěvky: 22

PříspěvekZaslal: 7. duben 2008, 13:58:10    Předmět: Odpovědět s citátem

eh, jasne sorry, samozrejme ze ma byt private, ale nechcelo sa mi pisat dalsiu funkciu getData (potrebujem to v main funkcii), ale pre spravnost mate pravdu... islo o iny problem v kode...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Al



Založen: 23. 10. 2007
Příspěvky: 196

PříspěvekZaslal: 7. duben 2008, 23:59:46    Předmět: Odpovědět s citátem

Divím se, že tak základní věci v té vaší knize nejsou. Základní myslím jako smrtelně důležité, ne jako jednoduché. Jistě uznáte, že toto je doslova smrtelné. Každá třída v C++ musí prostě mít mimo jasné věci i korektní "copy konstruktor" a "přiřazovací operátor". Cool

P.S. Doporučuji knihu M.Virius: Pasti a propasti C++
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 8. duben 2008, 00:06:40    Předmět: Odpovědět s citátem

Ne, každá třída nemusí. Pouze třídy vlastnící pointer do paměti musí ty kopírovací funkce mít a to jen tehdy, když je třeba při jejich kopii také kopírovat obsah paměti, kam pointery ukazují.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Al



Založen: 23. 10. 2007
Příspěvky: 196

PříspěvekZaslal: 8. duben 2008, 00:10:19    Předmět: Odpovědět s citátem

Podle mě musí každá třída, jak jsem napsal. Jen u těch triviálních, co uvádí Eosie, můžeme použít to, co tam automaticky vygeneruje překladač, a nemusíme to definovat sami.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna