Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kdo je autorem výstavy obrazových fotografií „Očima Hanse Christiana Andersena“?

V dnešní soutěži hrajeme o:



Problém s vložením objektu do zásobníku C++

Seznam témat     Nová odpověď

Přihlásit se     Registrace     Zapomenuté heslo

RE: Problem s vlozenim objektu do zasobniku C++

Autor: RSTEIN

6:48:53 29.03.2011

A jeste jedna prusviharska vec, kterou jsem vam nechtel prozradit rovnou.
Co se stane v metode push, kdyz index bude mit hodnotu 99?
Vy zkontrolujete v metode isFull, ze zasobnik neni plny. Pote index inkrementujete, index ma hodnotu 100 a vy ulozite do array[100] argument metody Push.
Jenze vase pole je indexovano od 0 do 99, zapsat na index 100 znamena, ze se v lepsim pripade zhrouti program, v horsim, ze pobezite s nakopnutym procesem dale. A tahle chyba je poradny prusvih.

RS

Příspěvek zaslán emailem

Citovat příspěvek

 

RE: Problem s vlozenim objektu do zasobniku C++

Autor: RSTEIN

22:08:36 28.03.2011

Rádo se stalo.;)
Každý jsme nejak zacinal, spis by me zajimalo, proc chce po vas vyucujici zalezitosti, ktere jsou spis antiidiomy a neverim, ze vam implementace zasobniku tohoto typu nejak zlepsi programatorske dovednosti v CPP. Pokud by slo o zkousku ze zakladnich datovych struktur, C# nebo Java by byly pro ukázky zásobníku lepší, protože CPP strhuje pozornost ke konstrukcím v samotném jazyce místo toho, abyste se věnoval hlavním vlastnostem zásobníku. Jediný důvod, proč někdo vyučuje tyhle ptákoviny, který mě napadl, je ten, že ho to před x lety přesně takto učil někdo jiný a že zadání takového příkladu je bezpracné-stačí obšlehnout popis zásobníku v CPP třeba z Eckela (který ale nevyžaduje ty nesmysly, co chtějí po Vás).

A jeste - ja tyhle sve prispevky beru jako pravidelne cviceni, ktere neuskodi. Treba hudebnici take stale cvici zaklady;)

Zdravim a drzim palce
Rene Stein

Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Problém s vložením objektu do zásobníku C++

Autor: Festo

21:41:53 28.03.2011

Není to sice efektivní, ale jako vzor ze kterého to pochopím, je to ideální :)

To, jak jste zavedl konstantu Invalid_Person, by mě nenapadlo, a funguje to vyborně. Problém s tím kopírováním objektů snad nějak vyřeším, když tak přímo zkusím prokonzultovat ve škole.

Každopádně Vám chci moc poděkovat za ochotu. Kdyby na Builder.cz bylo hodnocení uživatelu tak jako je třeba na Aukru nebo Ebay, tak za mě máte 10 bodu z 10 možných !! :)

Jako jediný jste se mi ozval, a udělal si čas s odepisováním a odpovídáním na mé dotazy, čehož si moc vážím. Abych pravdu řekl, nečekal jsem, že se mi někdo ozve, i když jsem na toto forum šel pro radu, protože jsem potřeboval poradit od zkušených programátorů jak jste Vy. Věřím, že moje téma zkušené programátory (jako jste Vy) asi moc nezajíma, jelikož to je hodně "Low level", ale jeden hodný se našel :)

Opravdu děkuji za Váš čas a ochotu, díky takovým má toto forum smysl použít, protože se mu dostane rady, na kterou žádná učebnice ( v mém případě :) ) neodpoví tak dobře, jako zkušenost druhých.

Děkuji

MC

Citovat příspěvek

 

RE: Problem s vlozenim objektu do zasobniku C++

Autor: RSTEIN

18:50:01 28.03.2011

Dobry den,
Snazil jsem se vase reseni zachovat, i když je neefektivni, protože se stále
kopiruji všechny objekty apod a trpi vsemi nesvary, co jsem jiz popisoval
vyse.

Diky zavedeni konstanty Invalid_Person mohu z metod top a pop vracet hodnotu
a podle INVALID_PERSON_ID poznam, ze jde o "neplatnou" osobu.
Osoba.h
#pragma once
#include
#include

class Osoba
{
private:
std::string jmeno;
std::string prijmeni;
int ID;

public:
Osoba();
Osoba(int id);
static const int INVALID_PERSON_ID = -10000;
static const Osoba& INVALID_PERSON;
void setOsoba(int n_ID, std::string n_jmeno, std::string
n_prijmeni);
void getOsoba();
virtual ~Osoba()
{

}
};


Osoba.cpp
#include "StdAfx.h"
#include "Osoba.h"

using namespace std;
Osoba::Osoba()
{

}

Osoba::Osoba(int id) : ID(id)
{

}

void Osoba::setOsoba(int n_ID, string n_jmeno, string n_prijmeni)
{
ID = n_ID;
jmeno = n_jmeno;
prijmeni = n_prijmeni;
}

void Osoba::getOsoba()
{
cout <<"ID: " << ID << endl;
cout <<"Jmeno: " << jmeno << endl;
cout <<"Prijmeni: " << prijmeni << endl;
}

const Osoba& Osoba::INVALID_PERSON = Osoba(Osoba::INVALID_PERSON_ID);

Zasobnik.h
#pragma once
#include "Osoba.h"

using namespace std;

const int N = 100;

class Zasobnik
{
private:
int index;
Osoba pole[N];

public:
bool isEmpty();
bool isFull();
void push(Osoba);
Osoba pop();
Osoba top();
Zasobnik();
virtual ~Zasobnik()
{

}
};

Zasobnik.cpp
#include "StdAfx.h"
#include
#include
#include "Zasobnik.h"

Zasobnik::Zasobnik()
{
index = -1;
}

bool Zasobnik::isEmpty()
{
return (index == -1);
}

bool Zasobnik::isFull()
{
return (index == N);
}

void Zasobnik::push(Osoba jedna)
{
if( ! isFull() )
{
index++;
pole[index] = jedna;
}

else
cout <<"Preteceni" <}

Osoba Zasobnik::top()
{
if( !isEmpty() )
return pole[index];

else
{
cout <<"Podteceni" << endl;
return Osoba::INVALID_PERSON;
}

}

Osoba Zasobnik::pop()
{
if( ! isEmpty() )
{
Osoba pomocna = top();
index--;
return pomocna;
}

else
{
cout <<"Podteceni" << endl;
return Osoba::INVALID_PERSON;
}
}


Main.cpp - způsobím "přetečeni"


#include "stdafx.h"
#include
#include
#include "Osoba.h"
#include "Zasobnik.h"

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
Zasobnik muj;
Osoba jedna;
Osoba dve;


jedna.setOsoba(1, "Michal", "Novak");
muj.push(jedna);


dve.setOsoba(2, "Karel", "Pribyl");
dve.getOsoba();


cout <<"Je prazdny: " << muj.isEmpty() <
cout <<"Je plny: " << muj.isFull() <
cout <
muj.push(dve);

cout <<"Je prazdny: " << muj.isEmpty() <
cout <<"Je plny: " << muj.isFull() <
Osoba osoba = muj.top();
osoba.getOsoba();
muj.pop();

Osoba osobaDalsi = muj.top();
osobaDalsi.getOsoba();
muj.pop();
cout <
Osoba osobaNull = muj.top();
osobaNull.getOsoba();
muj.pop();

muj.pop();
cout <
getchar();
return 0;
}

Vystup:
ID: 2
Jmeno: Karel
Prijmeni: Pribyl
Je prazdny: 0
Je plny: 0


Je prazdny: 0
Je plny: 0
ID: 2
Jmeno: Karel
Prijmeni: Pribyl
ID: 1
Jmeno: Michal
Prijmeni: Novak


Podteceni
ID: -10000
Jmeno:
Prijmeni:
Podteceni
Podteceni



Zdravim
Rene Stein
http://blog.renestein.net
twitter: http://twitter.com/renestein

Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Problém s vložením objektu do zásobníku C++

Autor: Festo

17:54:39 28.03.2011

Dobrý den,

snažím se bojovat, jelikož jsem v programování amatér, a po předchozí zkušenosti ted už vím, že pokud si to sám neuvědomím ( po napovědě, nebo ukazce), tak to je pro mě k ničemu, a jen to opsat je zbytečné, nic mi to nedá. Takže Vaše odpovědi si v hlavě převracím jak se dá :)

Je to přesně jak říkáte, metoda top() by neměla vypisovat aktuálního člověka, ale vracet ho. Napsal jsem to jinak, než jsem myslel :)

Mé .cpp soubory vypaddají:




#############################################

Zasobnik.cpp

#include "Zasobnik.h"

Zasobnik::Zasobnik()
{
index = -1;
}

bool Zasobnik::isEmpty()
{
return (index == -1);
}

bool Zasobnik::isFull()
{
return (index == N);
}

void Zasobnik::push(Osoba jedna)
{
if( ! isFull() )
{
index++;
pole[index] = jedna;
}

else
cout <<"Preteceni" <}

Osoba Zasobnik::top()
{
if( !isEmpty() )
return pole[index];

else
{
cout <<"Podteceni" << endl;
/*return;*/
}

}

Osoba Zasobnik::pop()
{
if( ! isEmpty() )
{
Osoba pomocna = top();
index--;
return pomocna;
}

else
{
cout <<"Podteceni" << endl;
/*return;*/
}
}

návratové hodnoty u put() a get() mám v komentu. Problém je bohůžel ten, že u těch problémových metod musíme mít výpis "Podtečení". Učitel na tom trvá.

######################################################

Osoba.cpp

#include "Osoba.h"

void Osoba::setOsoba(int n_ID, string n_jmeno, string n_prijmeni)
{
ID = n_ID;
jmeno = n_jmeno;
prijmeni = n_prijmeni;
}

void Osoba::getOsoba()
{
cout <<"ID: " << ID << endl;
cout <<"Jmeno: " << jmeno << endl;
cout <<"Prijmeni: " << prijmeni << endl;
}

Citovat příspěvek

 

RE: Problem s vlozenim objektu do zasobniku C++

Autor: RSTEIN

22:21:12 27.03.2011

Pravidlo jedne definice jsem predtim neposlal, tak je zde:
http://en.wikipedia.org/wiki/One_Definition_Rule

RS

N>
Příspěvek zaslán emailem

Citovat příspěvek

 

RE: Problem s vlozenim objektu do zasobniku C++

Autor: RSTEIN

22:18:55 27.03.2011

Dobry den,
Pravidlo jedne. Definice je dobre popsano treba zde:

Nevim, jak ted vypadaji vase cpp soubory (vracite v Top nebo Pop reference nebo pointer?), takze neodhadnu, kde je chyba. Metoda Top by cloveka vypisovat nemela, mela by ho jen vratit, to stale plati;)

Ale bojujete, to je lepsi, nez mit vse na stribrnem podnose a nevedet, jak ukrast prilozene zlate lzicky.;)

Zdravim
Rene Stein
http://blog.renestein.net
twitter: http://twitter.com/renestein

Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Problém s vložením objektu do zásobníku C++

Autor: Festo

21:02:38 27.03.2011

Tak přidáním Vámi doporučeného #pragma once do hlavičkových souborů došlo k tomu, že mi proběhla kompilace bez jakéhokoli erroru nebo upozornění :) Jak jste psal, je nutné mít ochranu před opakovanym vložením. Ted už tomu rozumím.

V mém případě beru jako úspěch :) Ba dokonce mi to pomocí funkce isEmpty() a isFull() ukazuje tak, jak má!

Musím se tedy zaměřit na ty metody top() a pop(), kompilátor je normálně veme, ale nevypíše třeba (metoda top() ) aktuálního člověka.... prostě neudělá nic.

Mohl bych Vás poprosit o stručné nastínění "pravidlo jedne definice" ... bohůžel jsem k němu nenašel nic, co by mi tento problém osvětlilo.

Děkuji za Váš čas, který se mnou řešíte můj problém.

Citovat příspěvek

 

RE: Problem s vlozenim objektu do zasobniku C++

Autor: RSTEIN

17:44:53 27.03.2011

Zacnete tou prvni chybou a dejte do h souboru direktivy #pragma once nebo#ifndef, jak jsem psal minule.
CPP cti dusledne pravidlo jedne definice a vy toto pravidlo svymi h soubory bez skrupuli znasilnujete.

Zdravim
Rene Stein
http://blog.renestein.net
twitter: http://twitter.com/renestein

Příspěvek zaslán emailem

Citovat příspěvek

 

Re: Problém s vložením objektu do zásobníku C++

Autor: Festo

16:29:20 27.03.2011

Diky za vysvětleni, už tomu zhruba rozumim. Ano, u metody Top a Pop mi to hlasi chyby, protoze tam nemam tu navratovou hodnotu. Zkusim vyhodit ten cout a vymyslet tu vyjimku.

Jen nechapu, proč to tak začal ten cvičící (cout << ...), když to není moc vhodné :)



Btw. výpis chyb z VS2010, který mi naskocí při kompilaci:



error C2011: 'Osoba' : 'class' type redefinition

error see declaration of 'Osoba'

error C2079: 'jedna' uses undefined class 'Osoba'

error C2079: 'dve' uses undefined class 'Osoba'

error C2228: left of '.setOsoba' must have class/struct/union

error C2664: 'Zasobnik::push' : cannot convert parameter 1 from 'int' to 'Osoba'

error C2228: left of '.setOsoba' must have class/struct/union

error C2228: left of '.getOsoba' must have class/struct/union

error C2664: 'Zasobnik::push' : cannot convert parameter 1 from 'int' to 'Osoba'


Sestavení SE NEZDAŘILO.

Citovat příspěvek

 

RE: RE: Problem s vlozenim objektu do zasobniku C++

Autor: RSTEIN

14:48:40 27.03.2011

A omlouvam se za ty preklepy a opakovani slov v prechozim prispevku, psano z
hlavy na PDA, kde klávesnice není zrovna idealni.

Rene Stein

Příspěvek zaslán emailem

Citovat příspěvek

 

RE: RE: Problem s vlozenim objektu do zasobniku C++

Autor: RSTEIN

14:41:22 27.03.2011

Dobry den,
ja nechci za vas vsechno napsat, ale:

1) Konstruktor se tyka instance - muzete nastavit, co chcete a pote mit u
osoby metody pro zmenu JEDNOTLIVYCH hodnot (setJmeno, setPrijmeni).

2) get metoda by mela vratit (ne vypsat) klientovi hodnotu vlastnosti, set
metoda u vlastnost nastavi novou hodnotu predanou klientem.

3) Viz předchozí poznamky. Jednoduse by trida mela mit alespoň jednoduše
pouzitelne rozhrani, citelny konstruktor a presnou sadu zavislosti. Vase
metoda setOsoba je pretizena, nedela jednu presne vymezenou věc, ale spis
supluje konstruktor. Navíc jsou vase trida Osoba jen "krabickou na data",
protože nema zadne chovani - pro ucely prikladu to ale asi staci.:)

C++
Ad 4) V C++ je dobře si zvyknout, ze inicializujete cleny instance v
inicializacni sekci konstruktoru, pokud to lze. Třeba u referenci dokonce
MUSITE používat inicializacni sekci.
Treba takto.
Zasobnik::Zasobnik() : index(-1)
{

}

Také by bylo vhodne zvazit zavedeni konstanty pro -1, když ji pouzivate na
vice mistech atd.

Ad 5) Pokud pocitate s tim, ze vase tridy mohou mit potomky a vy budete s
potomky pracovat pomoci pointeru/reference na bazovou tridu, destruktor musi
byt virtualni, jinak budete pri likvidaci odvozene instance pres pointer na
bazovou tridu "leakovat" pamet. To je jen turbouvod do problematiky,
existuje vice duvodu, proc udelat u trid vaseho typu destruktor virtualni.

virtual ~Zasobnik()
{

}

Ad 6) Mel jsem na mysli tridu