Problema Clase!!!

Intrebari despre limbajul C++, standardul C++, STL, OOP in C++ sau alte subiecte nelegate de VisualC++
Post Reply
yoyulian
Junior
Junior
Posts: 33
Joined: 05 Dec 2012, 14:53
Judet: Cluj

Problema Clase!!!

Post by yoyulian » 16 Apr 2013, 22:01

Salut, am incercat sa rezolv problema de mai jos, si de aicea nu mai stiu sa continui, nu are nici o eroare de compilare, programul dat; ma poate ajuta cineva!!!

Code: Select all

/*7.La un chiosc se vand ziare, reviste si carti. Fiecare publicatie are un nume, o editura, un numar de pagini, un numar de exemplare per 
publicatie si un pret. Scrieti clasa care modeleaza publicatiile. Adaugati un membru static valoare_tva si o metoda statica pentru modificarea 
valorii TVA-ului. Sa se calculeze suma totala pe fiecare tip de publicatie (ziare, reviste si carti) si pretul mediu pe pagina la fiecare publicatie 
in parte. Modificati TVA-ul si refaceti calculele. Afisati editurile in functie de incasari.*/



//directive procesor
#include<iostream>
using namespace std;


class Publicatie
{
	char nume[20];
	char editura[20];
	int nrpag;
	int nrexem;
	int pret;
public:
	Publicatie();
	~Publicatie()
	{
		cout<<"Se apeleaza destructorul!!!";
	}
	void static valoare_tva(int tva=24);
	float calc_tvaziare();
};

Publicatie::Publicatie()
{
		char n[20], e[20];  //declararea numelui si editurii
		int nr, exp, p;   //declararea nr=nrpagini, exp=nrexemplare, p=pret
		cout<<"Introduceti numele:";
		cin>>n;
		cout<<"Introduceti editura:";
		cin>>e;
		cout<<"Intorduceti nr de pagini:";
		cin>>nr;
		cout<<"Introduceti nr de exemplare:";
		cin>>exp;
		cout<<"Introduceti pretul(RON):";
		cin>>p;
		cout<<endl;
}

void main()
{
	int zar;
	int rev;
	int car;
	float *calc_tvaziare;
	int tva=24;
	cout<<"Cate \"ziare\" dorit sa introduceti in chiosc:";
	cin>>zar;
	Publicatie *ob1;
	ob1=new Publicatie[zar];
	calc_tvaziare= new float[zar];

	
	cout<<"Cate \"reviste\" doriti sa introduceti in chiosc:";
	cin>>rev;
	Publicatie *ob2;
	ob2=new Publicatie[rev];

	cout<<"Cate \"carti\" doriti sa introduceti in chiosc:";
	cin>>car;
	Publicatie *ob3;
	ob3=new Publicatie[car];

	Publicatie();


}



yoyulian
Junior
Junior
Posts: 33
Joined: 05 Dec 2012, 14:53
Judet: Cluj

Re: Problema Clase!!!

Post by yoyulian » 17 Apr 2013, 17:28

Ma poate ajuta careva va rog!!!

George92
Junior
Junior
Posts: 16
Joined: 13 Apr 2013, 00:37
Judet: Dolj

Re: Problema Clase!!!

Post by George92 » 17 Apr 2013, 20:29

pai faza cu tva-au ai facut o prostie, tu nu ai pus un membru ci o valoare default pt metoda aia statica. Trebuie sa ai o variabila statica in clasa gen : static int TVA, si o metoda statica gen: static void modificaTVA();

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Problema Clase!!!

Post by Silviu Ardelean » 17 Apr 2013, 20:34

Ceea ce ai schitat tu este foarte putin. Nu vad declararea si folosirea variabilei statice pentru TVA.

Intr-o rezolvare normala, problema data ar implica folosirea unei ierarhi de clase. Ai clasa de baza Publicatie abstracta a.i. sa nu se poata creea vreo instanta directa(ai o metoda virtuala pura) si cate o clasa derivata pentru fiecare tip efectiv (ziar, revista, carte).
In momentul in care creezi efectiv obiecte, acestea vor fi de tip concret: ziar, carte sau revista si setezi atributele corespunzatoare.

Implementeaza astea si povestim mai departe.

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Problema Clase!!!

Post by Marius Bancila » 18 Apr 2013, 11:17

Cine ti-a cerut sa pui un membru static pentru TVA a fost tampit. Banuiesc ca un profesor care habar nu are de programare si nu a gasit un exemplu mai bun pentru a va invata despre membrii statici.

In al doilea rand, ce cauta calc_tvaziare() in publicatie? Ce legatura are publicatia cu TVA-ul pentru ziare?

In al 3-a rand, te rog, nu mai folosi char* pentru stringuri. Foloseste std::string.

Uite, eu iti arat cum as face clasa Publicatie (fara ierarhii), si tu implementezi metodele ei.

Code: Select all

class Publicatie
{
   std::string nume;
   std::string editura;
   int nrpag;
   int nrexem;
   double pret;

   static double tva;
public:
   Publicatie(const std::string& nume="", const std::string& editura="", int pagini=0, int exemplare=0, double pret=0);
   ~Publicatie();

   static void set_tva(double tva = 24.0);

   void init(const std::string& nume, const std::string& editura, int pagini, int exemplare, double pret);
   double suma_total() const;
   double pret_pagina() const;
};
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

User avatar
Silviu Ardelean
Senior
Senior
Posts: 1175
Joined: 12 Jul 2007, 09:22
Judet: Timiş
Location: Timisoara
Contact:

Re: Problema Clase!!!

Post by Silviu Ardelean » 18 Apr 2013, 12:23

As zice ca atat timp cat TVA-ul are o valoare unica nu-i bai daca-i static si chiar ii determina pe studenti/elevi sa-l foloseasca in acest mod.
Daca in schimb e un TVA de Romania cu mai multe valori (cum de ex. se doreste la produsele de panificatie) atunci e BAI! :)

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Problema Clase!!!

Post by Marius Bancila » 18 Apr 2013, 18:38

Pai in multe tari TVA-ul e diferit pe produse diferite. In SUA e diferit si intre state. Asa ca...
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

yoyulian
Junior
Junior
Posts: 33
Joined: 05 Dec 2012, 14:53
Judet: Cluj

Re: Problema Clase!!!

Post by yoyulian » 18 Apr 2013, 20:47

Multumesc mult la toti!!! Eu v-am dat enuntul exact cum ne-a dat profesorul, iar problema eu am implementat-o cum am stiu eu.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Problema Clase!!!

Post by Ovidiu Cucu » 19 Apr 2013, 12:39

Probabil ca da, profu v-a pus sa bagati membrul ala static tocmai ca sa vada elevii la ce foloseste si cum se foloseste asa ceva. E de inteles, asa ca n-are rost sa ne bagam prea tare in chestii de "design".
E mai greu insa de inteles de ce se insista pe combinatia asta sado-masochista intre STL si array-uri C-style.
Eu zic asa. Sa-l prinzi pe prof intr-o pasa buna intre-o pauza si sa-l intrebi: "Dom' profesor, daca am declarant char nume[20] cum fac sa n-am probleme atunci cand il introduce de la consola si are mai mult de nouasprezece litere?" (vezi discutia noastra anterioara).
Daca stie cum, atunci spune-mi te rog si mie cum a facut, si-mi scot palaria in fata lui. :)

Daca deja folositi chestii din STL si daca de-acuma ati trecut la clase (OOP, in general), n-are rost sa va mai chinuie si nu cred ca i-ar lua mai mult de o ora sa va spuna pe scurt ce si cum e si cum se poate folosi std::string, eventual si std::vector.

Tot in discutia anterioara ti-am sugerat ca in constructor e bine ca sa faci doar oaresce initializari default sau cu valori care vin ca parametri.
Din nou, scoate citirea de la consola din constructor si pune-o intr-o functie separata!

Ar mai fi si alte observatii, de exemplu ca Publicatie ar trebui sparta in mai multe clase, insa am zis de la inceput ca nu ma leg de design.

yoyulian
Junior
Junior
Posts: 33
Joined: 05 Dec 2012, 14:53
Judet: Cluj

Re: Problema Clase!!!

Post by yoyulian » 21 Apr 2013, 14:27

Te inteleg Ovidu dar eu asa m-am obisnuit sa fac, tot timpul am pus o dimensiune la un sir cum ar fi char nume; are importanta daca dam dimensiunea 20? M-am luat dupa niste exemple dintr-o carte pe care n-a dat-o la scoala, stiu ca sunt multe lucruri care ar trebui sa le facem. Si in ceea ce priveste constructorul, trebuia sa fac functii separate dar, ma gandeam ca asa iese mai usor. Inainte de a incepe exercitul de mai sus, m-am uitat pe exemplul pe care mi l-ai facut tu data trecuta cu ”Studenti” dar, nu prea am inteles cum dai dimensiunea unui sir si nu m-am mai complicat.

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Problema Clase!!!

Post by Marius Bancila » 22 Apr 2013, 10:56

Cum ziceam acum 2 minute, scoala in Romania, a ramas undeva la 1985.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Problema Clase!!!

Post by Ovidiu Cucu » 22 Apr 2013, 12:13

Marius Bancila wrote:Cum ziceam acum 2 minute, scoala in Romania, a ramas undeva la 1985.
Asa avansata? Nuuuu-i adevarat! :D
In '85 erau inca FORTRAN si COBOL la mare cinste, insa se invatau libaje de programare cap-coada si la modul serios. ;)
yoyulian wrote:Te inteleg Ovidu dar eu asa m-am obisnuit sa fac, tot timpul am pus o dimensiune la un sir cum ar fi char nume;
Imi pare bine ca macar manifesti intelegere fata de mine... :)
Tin totusi sa precizez ca in programare "obisnuniţa" este unul dintre cei mai contra-productivi factori. Un programator bun trebuie sa accepte ideea ca mereu e loc pentru mai bine si ca mereu trebuie invatate chestii noi.
yoyulian wrote:are importanta daca dam dimensiunea 20?
Da, are. Am mai spus, insa o sa explic inca o data mai jos.
yoyulian wrote:M-am luat dupa niste exemple dintr-o carte pe care n-a dat-o la scoala, stiu ca sunt multe lucruri care ar trebui sa le facem.
Foarte bine. Retine insa ca multe carţi / manuale de "C++" sunt depasite si/sau sunt scrise de autori "mucegaiti" si/sau sunt la un nivel destul de jos, pentru ca sa absolve tot elevul puturos.
Nu-i chiar foarte rau sa inveti dupa ele, poti deprinde ceva notiuni de baza si de-acolo. Insa, cum am mai spus la inceput, este loc si de mai bine. Daca vrei sa devii un programator C++ bun, trebuie sa treci dincolo de ele.
yoyulian wrote:Si in ceea ce priveste constructorul, trebuia sa fac functii separate dar, ma gandeam ca asa iese mai usor.
Aparent mai usor. Nu te doare mana sa adaugi o noua metoda, daca asa e mai bine. Daca de exemplu (cum cred ca am mai spus in alt topic), in afara de citirea de la consola se iveste necesitatea sa citesti dintr-un fisier, ce facem? Dam cu barda in constructor? Retine: "datul cu barda" sau mai frumos spus, modificarea unui cod deja scris e mai grea decat extinderea lui (e mai usor da adaug o metoda noua decat sa modific una existenta).
yoyulian wrote:Inainte de a incepe exercitul de mai sus, m-am uitat pe exemplul pe care mi l-ai facut tu data trecuta cu ”Studenti” dar, nu prea am inteles cum dai dimensiunea unui sir si nu m-am mai complicat.
Aici nu stiu exact lace te referi. Daca luam totusi problema in discutie si anume acei membri nume, editura care tin un text (string), nu trebuie sa-ti bati capul cu dimensiunea daca-i pun de tipul std::string, asa cum am face de exemplu folosind unsir de caractere C-style (ex. char nume[N]).
Altfel zis, are grija clasa std::string cate caractere sa aloce atunci cand de exemplu il citesc de la consola (ceva de genul std::cin >> nume;).

Hai sa luam ca exemplu de pornire, cateva posibile implementari a unei clase care contine un nume.

Code: Select all

class CFoo1
{
   char nume[20];
   // ...
};
Pare simplu, insa nu e. Trebuie sa ma asigur ca, de exemplu, utilizatorul nu introduce la consola mai mult de 19 caractere. Altfel, stringul introdus "da pe dinafara" iar programul poate crapa la run-time cu strigaturi.
E posibil, de exemplu, sa faci in asa fel incat sa limitezi numarul de caractere introduse, insa destul de naspa daca nu cunosti despre stream-uri ceva mai mult decat se invata la scoala, adinca chestii de genul (cin >> nume;).
Bine-bine, zici atunci ca declari un array cu suficient de multe elemente (sute, mii) in asa fel incat sa fie "acoperitor". Nici asta nu-i OK. Daca ai la un momentdat multe instante de obiecte tip CFoo (si mai pui si cazul ca poate contine fiecare mai multe array-uri de acest fel), atunci incarci biata stiva mergand pana la a avea stack overflow. Stiva este o zona de memorie cu dimensiune relativ mica, este folosita nu numai la tinut date pe ea, asa ca e bine sa ai mila de ea si sa n-o incarci prea mult.
Asa ca, un pas inainte este sa folosesti pentru nume alocare dinamica, care se face in memoria heap, speciala pentru tinut date cu dimensiuni mari si/sau dimensiuni care nu sunt "batute-n cuie" sau cu alte cuvinte, nu sunt cunoscute la "programming time".

Deci, un pic mai bine, avem

Code: Select all

class CFoo2
{
   char* nume;
   unsigned int lungime_nume;
   // ...
};
In continuare, folosesc functii C de alocare si dealocare dinamica cum ar fi malloc si free sau, daca tot lucram cu C++, operatorii new si delete.
E destul de naspa si asa, pentru ca trebuie avut grija cat si cand aloc, cand dezaloc, de initializat acel pointer cu NULL sau de pus pe NULL ininte de o noua alocare, sa fac curatenie in destructor, si alte chestii hazlii de genul asta.
In plus, este o abordare destul de non-OOP. Daca mai am si alte stringuri membre de acest gen, atunci trebuie sa fac acelasi lucru pentru fiecare dintre ele. That's a real overkill.

Asa ca, luam OOP-ul in brate si implementam propria clasa pentru stringuri, sa-i zicem String.

Code: Select all

class String
{
   char* nume;
   unsigned int size;
   // ...
};

class CFoo3
{
   String nume;
   // ...
};
Aceleasi probleme ca si la precedenta insa ai marele avantaj ca implementezi clasa String o data si pentru totdeauna, apoi o folosesti oriunde si oridecate ori ai nevoie.

Buuun... hai sa luam o mica pauza si sa citez o reclama care se dadea mai demult la TV.
"Ce faci tata?"
"Prepar un suc de portocale."
"Pentru ce atata munca, cand e gata preparat? Si are si vitamina C. :D
Revenind la problema noastra: pentrtu ce atata munca, cand exista jdemii de clase pentru stringuri, gata implementate in diverse biblioteci?
Una la indemana tuturor programatorilor C++ este cea din STL, std::string.
Deci, putem face simplu:

Code: Select all

#include <string>

class CFoo4
{
   std::string nume;
   // ...
};
Nu mai trebuie sa am grija de alocari, dezalocari, etc. In plus, contine metode utile si operatori pentru lucru cu stringuri (concatenari, comparatii, etc) care ti-ar da destula durere de cap daca te-ai apuca sa le implementezi "la mana", singur.

In concluzie, daca tot ai trecut la clase si alte chestii OOP, n-are rost sa ramai agatat de chestii mostenite din C (cum ar fi array-urile) sau sa te apuci de reinventat roata. E bine sa stii si din alea, pune-le undeva la pastrare pentru ca te mai intalnesti din cand in cand cu ele, insa treci la pasul urmator...

yoyulian
Junior
Junior
Posts: 33
Joined: 05 Dec 2012, 14:53
Judet: Cluj

Re: Problema Clase!!!

Post by yoyulian » 22 Apr 2013, 22:17

Sper ca dupa cativa ani sa stiu atatea lucruri despre programare; eu in liceu nu am facut programare doar acum de cateva luni m-am apucat sa invat programare.

Inainte de a incepe exercitul de mai sus, m-am uitat pe exemplul pe care mi l-ai facut tu data trecuta cu ”Studenti” dar, nu prea am inteles cum dai dimensiunea unui sir si nu m-am mai complicat.
Aici m-am referit ca in exemplul pe care mi l-ai facut nu am inteles cum ai alocat spatiu pentru studenti, note, medii, si mai ce era pe acolo.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Problema Clase!!!

Post by Ovidiu Cucu » 28 Apr 2013, 19:02

Scuze, ramasesem dator aici cu oaresce explicatii, asa ca le dau acum desi cred ca unele le repet. ;)
Referitor la:
yoyulian wrote:
Inainte de a incepe exercitul de mai sus, m-am uitat pe exemplul pe care mi l-ai facut tu data trecuta cu ”Studenti” dar, nu prea am inteles cum dai dimensiunea unui sir si nu m-am mai complicat.
Aici m-am referit ca in exemplul pe care mi l-ai facut nu am inteles cum ai alocat spatiu pentru studenti, note, medii, si mai ce era pe acolo.
Pentru studenti, note si de mai era pe acolo NU am alocat direct si explicit nimic. Toate alocarile sunt facute dinamic in clasele din STL (std::string, std::vector sau std::istream).
De exemplu, daca am

Code: Select all

   std::cin >> m_sNume;
unde m_sNume este de tipul std::string alocarea se face in operatorul >> din istream in asa fel incat sa incapa in m_sNume exact cate caractere am introdus de la consola.
Sau daca am

Code: Select all

   m_vNote.resize(nr_discipline);

unde m_vNote este de tipul std::vector se aloca in functia resize atat cat sa incapa nr_discipline elemente.

yoyulian
Junior
Junior
Posts: 33
Joined: 05 Dec 2012, 14:53
Judet: Cluj

Re: Problema Clase!!!

Post by yoyulian » 30 Apr 2013, 20:58

Mumtumesc mult pentru felul cum tratezi lucrurile(adica cu mare seriozitate, incerci sa explici cate mai multe).

Post Reply