Ukazatel ve třídě pomocí new – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Ukazatel ve třídě pomocí new – C / C++ – Fórum – Programujte.comUkazatel ve třídě pomocí new – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
Hlavinka0
Návštěvník
26. 9. 2012   #1
-
0
-

Dobrý den,

chtěl jsem si jen tak pro radost procvičit třídy, ale nějak se mi to vymklo z rukou, protože mi to háže assertion failure a netuším co bych měl na to zdrojáku opravit :-)

#include <iostream>
#include <cstring>

using namespace std;

class tri {
      private:
            int x;
            double n;
            bool y;
            int *z;
			void vynuluj(){*z = 0;};
			void pricti(int a){*z += a;};
      public:
             explicit tri(int xx, double nn, bool yy, int zz):x(xx), n(nn), y(yy){z = new int;*z = zz;};  //deklarace i definice konstruktoru zkracena verze
             tri operator=(tri &a);
             tri operator+(tri &a);
             friend ostream & operator<<(ostream &os, tri &a);
			 int ukazz(){return *z;};
             ~tri();
             };
             
int main()
{
    tri x(5, 6.3, true, 10), y(7, 3.3, true, 1), z(2, 16.3, false, 5), a(0, 0.0, false, 0);
    cout << "x: " << x << "y: " << y << "z: " << z;
    a = x + y;
    cout << "a = x + y: " << a;
    a = x + z;
    cout << "a = x + z: " << a;
    a = x + y + z;
    cout << "a = x + y + z: " << a;
    
    system("pause");
    return 0;
}

tri tri::operator=(tri &a) 
{
   x = a.x;
   n = a.n;
   y = a.y; 
   delete z;
   z = new int;
   *z = a.ukazz();
   return *this;
}
tri tri::operator+(tri &a)
{
   tri b(0, 0.0, false, 0);
   b.x = x + a.x;
   b.n = n + a.n;
   if(y == true && a.y == true)b.y = true;
   else b.y = false;
   b.vynuluj();
   b.pricti(ukazz());
   b.pricti(a.ukazz());
   return b;
}
ostream & operator<<(ostream &os, tri &a)
{
   os << a.x << ' ' << a.n << ' ' << a.y << ' ' << a.ukazz() << endl;
   return os;
}
tri::~tri()
{
   delete z;
}

podle me je nejaka nejaka chyba v tech pretizenych operatorech = a +, ale vubec netusim jaka :-) dekuji predem za pomoc a postrehy

Nahlásit jako SPAM
IP: 188.175.185.–
nergal+1
Návštěvník
26. 9. 2012   #2
-
0
-

zkusil by som to takto pisem len upravene casti:

class tri {
      private:
            int x;
            double n;
            bool y;
            int *z;
			void vynuluj(){*z = 0;};
			void pricti(int a){*z += a;};
      public:
             explicit tri(int xx, double nn, bool yy, int zz):x(xx), n(nn), y(yy){z = new int;*z = zz;};  //deklarace i definice konstruktoru zkracena verze
             tri& operator=(const tri &a);
             const tri operator+(const tri &a) const;
             friend ostream & operator<<(ostream &os, tri &a);
	     int ukazz()const{return *z;};
             ~tri();
             };

tri& tri::operator=(const tri &a) 
{
   x = a.x;
   n = a.n;
   y = a.y; 
   delete z;
   z = new int;
   *z = a.ukazz();
   return *this;
}
const tri tri::operator+(const tri &a) const
{
   tri b(0, 0.0, false, 0);
   b.x = x + a.x;
   b.n = n + a.n;
   if(y == true && a.y == true)b.y = true;
   else b.y = false;
   b.vynuluj();
   b.pricti(ukazz());
   b.pricti(a.ukazz());
   return b;
}
Nahlásit jako SPAM
IP: 85.135.128.–
viem že neviem čo viem
KIIV
~ Moderátor
+43
God of flame
26. 9. 2012   #3
-
0
-

*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0000000001169070 ***

(teda pote, co sem poopravoval par veci - const u operatoru a ukazz)

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Řešení
KIIV
~ Moderátor
+43
God of flame
26. 9. 2012   #4
-
0
-
Vyřešeno Nejlepší odpověď

minimalne nemas copy constructor ... tim se ti okopiruje objekt vcetne pointeru pomoci defaultniho cc

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
nergal+1
Návštěvník
26. 9. 2012   #5
-
0
-

#4 KIIV
u mna to prejde aj cez valgrind bezchybne po pridani const do operatorov a ukazz().
imho copy konstruktor sa nepouziva tak nieje potrebny...

Nahlásit jako SPAM
IP: 85.135.128.–
viem že neviem čo viem
KIIV
~ Moderátor
+43
God of flame
26. 9. 2012   #6
-
+1
-
Zajímavé

#5 nergal
ee g++ to 100% s copy konstruktorem pouzije... kdyz ho hodim do private tak to pozaduje implementaci

a kdyz pridam tak to krasne zkompiluje a zadnej segfault

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
26. 9. 2012   #7
-
0
-

Presne tak, návratové hodnoty operátorov niesu referencie, takže sa tam môže volať kopírovací konštruktor.

edit: Prekladač ale môže alokovať lokálnu premennú 'b' mimo rozsah metódy a pri vrátení premennej 'b' z metódy sa nevolá kopírovací konštruktor (definovaný ale musí byť). Záleží od prekladača a optimalizácii čo robí.

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Hlavinka0
Návštěvník
26. 9. 2012   #8
-
0
-

super :-) děkuji moc, kopirovaci konstruktor mi vyletel z hlavy :-) stacilo ho dodat a funguje to v pohode zkusim jeste tam dohodit ty consty, ale jeste ze to neni uplne nutne :-)

Nahlásit jako SPAM
IP: 188.175.185.–
ondra.holub+1
Stálý člen
26. 9. 2012   #9
-
0
-

#6 KIIV
Někdy je copy ctor potřeba jenom syntakticky (takže musí být přístupný), ale překladač ho může vyoptimalizovat (jak psal níže vitamin).

Každopádně u přiřazovacího operátoru je klasická chyba - chybí kontrola, jestli nepřiřazuju do sebe. Pokud ano, tak se nejdříve udělá delete z a pak se udělá *z = *z (i když je to schované ve volání ukazz()). V tomto případě tedy zůstane *z jenom nenainicializované, ale jindy to může vést i k neoprávněnému přístupu do paměti.

Nahlásit jako SPAM
IP: 212.96.189.–
vitamin+8
Grafoman
26. 9. 2012   #10
-
0
-

#9 ondra.holub
Skôr mi príde divné prečo dealokuje integer a hneď ho zas alokuje...

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Hlavinka0
Návštěvník
27. 9. 2012   #11
-
0
-

ondra.holub ->

tu kontrolu jsem vynechal naschvál, protože je to zkušební třída, kterou nebudu používat, ale máš pravdu, že je dobré ji udělat  :-)

vitamin ->

a to jsem si ani pořádně neuvědomil, já radši s new zacházím opatrně a radši jsem to napsal tak :-)

Nahlásit jako SPAM
IP: 188.175.185.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 14 hostů

Podobná vlákna

Ze by ukazatel ... — založil Marecek

Ukazatel — založil porod

Ukazatel this — založil LPG1995

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý