Chiarimento dubbi C++

slevyn
Salve ragazzi...ho cominciato da poco a trattare il c++ ..purtroppo non mi sono chiare alcune cose . Prendendo di esempio questa piccola esercitazione , dove ho diviso il file.h e le implementazioni dei metodi
#define _ESAME_H
#include<iostream>
#include <string>
using namespace std;
class esame {
   public:
   esame();  // costruttore di default
   esame(string); // imposta il nome dell'esame
   esame(string,int); //imposta nome e voto dell'esame
   string getEsame();
   void setEsame(); // imposta il nome dell'esame;
   int getVoto(int); // restituisce il voto
   void setVoto() ;// imposta il voto dell'esame
   void visualizzaVoto();
   void visualizzaEsame();
   private:
   string NomeEsame;
   int voto;
   bool sostenuto;
};
#endif _ESAME_H


#include<iostream>
#include <string>
#include "esame.h"
using namespace std;
esame::esame()
{
    esame(NomeEsame,voto);
}

esame::esame(string NomeEsame)
{
    cout<<"Inserire il nome dell'esame: ";
    cin>>NomeEsame;
}

esame::esame(string NomeEsame,int voto)
{
    cout<<"Inserire il nome dell'esame: ";
    cin>>NomeEsame;
    cout<<endl;
    cout<<"Inserire il voto dell'esame specificato: ";
    cin>>voto;
}

string esame::getEsame()
{
    return NomeEsame;
}


void esame::setEsame()
{
   cout<<"Inserire il nome dell'esame: ";
    cin>>NomeEsame;
}


void esame::setVoto()
{
    cout<<"Inserire il voto dell'esame: ";
    cin>>voto;
}


void esame::visualizzaEsame()
{
    cout<<"L'esame è :"<<NomeEsame;
}

void esame::visualizzaVoto()
{
    cout<<"L'esame è :";
    cout<<NomeEsame;
}

Il mio problema è che non capisco come applicare questi metodi nel main...cioè come applicare quei metodi . Per esempio ho utilizzato il costruttore "esame()" il quale mi permette di inserire il nome e il voto dell'esame...Poi ho richiamato il metodo "visualizzaEsame()" , ma non mi restituisce il nome dell'esame che ho inserito poco prima...sto facendo molta confusione..

Risposte
vict85
Quella libreria è implementata malissimo. La presenza di visualizzaEsame e visualizzaVoto è insensata in presenta di getEsame e getvoto. I costruttori non fanno quello che dovrebbero e le funzioni richiamano inutilmente le funzioni di iostream quando sarebbe meglio se gli inviassi direttamente i valori. Quindi in pratica è una libreria da buttare.

Ecco come avrebbe dovuto essere fatta:

#ifndef _ESAME_H
#define _ESAME_H

#include <string>


class esame {

	public:

	esame();  // costruttore di default
	esame(std::string const); // imposta il nome dell'esame
       esame(std::string const, int const); //imposta nome e voto dell'esame

       std::string const getEsame() const;
       void setEsame(std::string const); // imposta il nome dell'esame;
       int const getVoto() const; // restituisce il voto
       void setVoto(int const) ;// imposta il voto dell'esame

    private:

       std::string NomeEsame;
       int voto;
       bool sostenuto;
};
	
#endif


#include <string>
#include "esame.h"

esame::esame() {};

esame::esame(std::string const Nome) :
NomeEsame(Nome),
voto(0) {};

esame::esame(std::string const Nome, int const v) :
NomeEsame(Nome),
voto(v) {};

std::string const esame::getEsame() const
{
	std::string const ret(esame::NomeEsame);
    return ret;
}


void esame::setEsame(std::string const Nome)
{
   esame::NomeEsame = Nome;
}


void esame::setVoto(int const v)
{
    esame::voto = v;
}

int const esame::getVoto() const
{
	int const v = esame::voto;
	return v;
}


Ovviamente ci sono altre cose che in realtà andrebbero aggiunte/modificate per renderla una utilizzabile ma ci avrei messo più tempo a farle.

slevyn
Grazie per i consigli ..ma volevo capire alcune cose :
1) perchè hai utilizzato std al posto di nominare using namespace std
2) il motivo dell'utilizzo di 3 costruttori ..non posso utilizzarne solo uno ?

slevyn
Inoltre definendo una classe derivata del tipo

ifndef _STUDENTE_H
#define _STUDENTE_H
#include <iostream>
#include "esame.h"
#include <string>

using namespace std;

class studente:protected esame
{
    protected:
    int matricola;
    esame libretto[5];
    int media;

    public:
    studente();
    studente(string const,string const,string const , string const ,string const);
    void setMatricola(int const); // imposta la matricola dello studente
    void setEsame(string const);  // imposta il nome dell'iesimo esame
    int const getEsame();  // restituisce il nome dell'i-esimo esame
    bool getSostenuto(int);// restituisce se l'i-esimo esame è stato sostenuto
    int mediaEsami();
    void printStudente() ;// visualizza tutte le informazioni dello studente !
};
#endif



se voglio implementare il costruttore studente(string const,string const...) , ovvero il costruttore che assegna il nome a ciascun elemento del vettore " esami libretto[5] " ..come faccio ? ..

vict85
"slevyn":
Grazie per i consigli ..ma volevo capire alcune cose :
1) perchè hai utilizzato std al posto di nominare using namespace std
2) il motivo dell'utilizzo di 3 costruttori ..non posso utilizzarne solo uno ?


1) Beh, ci sono buone ragioni per non introdurre tutto il namespace std ma scrivere std:: in ogni caso più che usare using namespace std sarebbe meglio usare introdurre solo quelli che effettivamente usi. In alcuni casi lavori su namespace che hanno definito funzioni e classi con lo stesso nome e quindi separare i namespace è meglio. Ma forse non sai esattamente neanche cos'è un namespace e quindi sono cose per il futuro
2) puoi definirne anche uno solo

vict85
"slevyn":
Inoltre definendo una classe derivata del tipo

ifndef _STUDENTE_H
#define _STUDENTE_H
#include <iostream>
#include "esame.h"
#include <string>

using namespace std;

class studente:protected esame
{
    protected:
    int matricola;
    esame libretto[5];
    int media;

    public:
    studente();
    studente(string const,string const,string const , string const ,string const);
    void setMatricola(int const); // imposta la matricola dello studente
    void setEsame(string const);  // imposta il nome dell'iesimo esame
    int const getEsame();  // restituisce il nome dell'i-esimo esame
    bool getSostenuto(int);// restituisce se l'i-esimo esame è stato sostenuto
    int mediaEsami();
    void printStudente() ;// visualizza tutte le informazioni dello studente !
};
#endif



se voglio implementare il costruttore studente(string const,string const...) , ovvero il costruttore che assegna il nome a ciascun elemento del vettore " esami libretto[5] " ..come faccio ? ..


A che ti serve imporre le variabili come protected? Puoi lavorare tranquillamente con le variabili private. Inoltre direi che sarebbe meglio usare un vector di esami (anche se a seconda degli usi potrebbe essere meglio creare una classe libretto che gestisca il libretto) più che un array.

Riguardo invece al costruttore direi che è meglio se crei solo un costruttore di default e poi gli esami li aggiungi dopo.

slevyn
Grazie per le risposte..un ultima cosa è come gestire le derivazione ...ovvero che modalità di accesso imporre per esempio alle due classi Esame e Studente che ho prima linkato

vict85
Non c'è nessuna ragione di derivare: uno studente non è un esame ma possiede un libretto che contiene esami. Quindi il loro legame è solo Studenti possiede un array (o ancora meglio un vector) di tipo esame.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.