Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2014
    Messaggi
    55

    [C++] Costruttori definiti fuori o dentro la classe

    Salve Ragazzi, non capisco perchè ho sempre problemi quando definisco i costruttori fuori dal corpo classe:
    codice:
    //Persona.h
    #ifndef PERSONA_H
    #define PERSONA_H
    #include "Data.h"
    using namespace std;
    
    class Persona{
    public:
        Persona();
        Persona(string,string,Data);
        virtual void print()=0;
    protected:
        string nome;
        string cognome;
        Data date;
    };
    
    class Studente : public Persona{
    public:
        Studente ();
        Studente (string a, string b, Data c, string d);
        virtual void print();
        ~Studente();
    protected:
        string CDL;
    };
    
    class Docente : public Persona{
    public:
        Docente ();
        Docente (string a,string b,Data c,string d);
        virtual void print();
        ~Docente();
    private:
        string Materia;
    };
    
    class StudenteSpecialista : public Studente{
    public:
        StudenteSpecialista ();
        StudenteSpecialista (string,string,Data,string,string);
        virtual void print();
        ~StudenteSpecialista();
    private:
        string LT;
    };
    
    #endif
    codice:
    //Persona.cpp
    #include <iostream>
    #include "Persona.h"
    #include "Data.h"
    using namespace std;
    
    
    Persona::Persona(){
        nome="-";
        cognome="-";
    }
    
    Persona::Persona(string a, string b, Data c){
        nome=a;
        cognome=b;
        date=c;
    }
    
    
    
    Studente::Studente(){
        Persona();
        CDL="-";
    }
    
    Studente::Studente(string a,string b,Data c,string d){
        Persona(a,b,c);
        CDL=d;
    }
    
    void Studente::print(){
        cout<<nome<<endl<<cognome<<endl<<date<<endl<<CDL<<endl<<endl;
    }
    
    Docente::Docente(){
        Persona();
        Materia="-";
    }
    
    Docente::Docente(string a, string b, Data c, string d){
        Persona (a,b,c);
        Materia=d;
    }
    
    Studente::~Studente(){
        cout<<"Distruttore"<<endl;
    }
    
    Docente::~Docente(){
        cout<<"Distruttore"<<endl;
    }
    codice:
    ||=== Build: Debug in ese5 (compiler: GNU GCC Compiler) ===|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp||In constructor 'Studente::Studente()':|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp|21|error: cannot allocate an object of abstract type 'Persona'|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.h|6|note:   because the following virtual functions are pure within 'Persona':|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.h|10|note:     virtual void Persona::print()|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp||In constructor 'Studente::Studente(std::string, std::string, Data, std::string)':|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp|26|error: cannot allocate an object of abstract type 'Persona'|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.h|6|note:   since type 'Persona' has pure virtual functions|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp||In member function 'virtual void Studente::print()':|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp|31|error: cannot bind 'std::basic_ostream<char>::__ostream_type {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'|
    c:\program files\codeblocks\mingw\lib\gcc\mingw32\4.8.1\include\c++\ostream|602|error:   initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Data]'|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp||In constructor 'Docente::Docente()':|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp|35|error: cannot allocate an object of abstract type 'Persona'|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.h|6|note:   since type 'Persona' has pure virtual functions|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp||In constructor 'Docente::Docente(std::string, std::string, Data, std::string)':|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.cpp|40|error: cannot allocate an object of abstract type 'Persona'|
    C:\Users\Vinc\Desktop\Bill\Bill_ese_9\ese5\Persona.h|6|note:   since type 'Persona' has pure virtual functions|
    ||=== Build finished: 6 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|
    il main è un semplice file di prova..
    codice:
    //main.cpp
    #include <iostream>
    #include "Persona.h"
    #include "Data.h"
    using namespace std;
    
    int main(){
        Studente l;
        Docente d;
    }
    Ultima modifica di MItaly; 15-01-2015 a 09:42 Motivo: Aggiunti tag CODE

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Perché stai sbagliando:
    codice:
    Studente::Studente(string a,string b,Data c,string d){
            Persona(a,b,c); // non ha proprio senso.
        CDL=d;
    }
    Nello specifico stai creando un oggetto Persona all'interno del costruttore di Studente. E persona è una classe virtuale pura.
    Per passare i parametri da classe derivata a classe base dev'essere:
    codice:
    Studente::Studente(string a,string b,Data c,string d) : Persona(a,b,c) {
        CDL=d;
    }
    E se non fornisci un'implementazione a Docente:: print() avrai un altro errore.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jun 2014
    Messaggi
    55
    Grazie per la risposta.. E se ometto Il "Persona(a,b,c)" dopo i due punti è un errore? Non dovrebbe inizializzare a,b,c, di default?

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Quote Originariamente inviata da vicio_93 Visualizza il messaggio
    Grazie per la risposta.. E se ometto Il "Persona(a,b,c)" dopo i due punti è un errore?
    Se il costruttore della classe derivata è parametrico è obbligatorio passare i parametri al costruttore parametrico della classe base.

    Se non usi il costruttore parametrico, la chiamata è implicita.
    codice:
    Non dovrebbe inizializzare a,b,c, di default?
    E a cosa dovrebbe inizializzarli? Con quello che vuoi tu o con quello che vuole lui? Riflettici un po' su.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jun 2014
    Messaggi
    55
    Grazie 1000

  6. #6
    Utente di HTML.it
    Registrato dal
    Jun 2014
    Messaggi
    55
    A che ci sono chiedo subito un'altra cosa: perchè quando utilizzo un metodo set per settare un certo parametro devo passare per forza per valore:
    codice:
    void Persona::SetNome(string a){
        nome=a;
    }
    Non si può passare per riferimento?
    codice:
    Poi string Persona::GetNome()const{
        return nome;
    }
    non posso fare la stessa cosa, cioè quella di ritornare per riferimento? Grazie in anticipo
    Ultima modifica di MItaly; 15-01-2015 a 09:42 Motivo: Aggiunti tag CODE

  7. #7
    Utente di HTML.it L'avatar di minomic
    Registrato dal
    Nov 2010
    Messaggi
    635
    Non mi risulta che sia così. Infatti guarda questo piccolo esempio:

    codice:
    #include <iostream>
    
    class Numero
    {
    public:
        Numero() {};
    
        void setNumero(int& num) {numero = num;}
        const int& getNumero() {return numero;}
    
    private:
        int numero;
    };
    
    
    int main(int argc, char const *argv[])
    {
        Numero n;
        int v = 1;
    
        n.setNumero(v);
    
        const int& a = n.getNumero();
    
        std::cout << "Numero: " << a << std::endl;
        return 0;
    }

    Poi, ci sono ovviamente dei problemi. Ad esempio, nell'esempio sopra non puoi fare

    codice:
    n.setNumero(2);

    perché devi comunque passare un int&.

  8. #8
    Utente di HTML.it
    Registrato dal
    Jun 2014
    Messaggi
    55
    Va bene. Per ultimo quando per esempio invoco il costruttore di una classe base per una derivata se utilizzo gli stesso nomi posso avere un conflitto di nomi?

    es.
    codice:
    Persona::Persona(string a, string b, string c){...}
    
    Studente::Studente (string a, string b, string c, string d) : Persona (a,b,c){...}
    Ultima modifica di MItaly; 15-01-2015 a 09:42 Motivo: Aggiunti tag CODE

  9. #9
    Utente di HTML.it
    Registrato dal
    Jun 2014
    Messaggi
    55
    Poi quando compilo mi da un errore nella get dicendo che devo ritornare un riferimento a costante no un riferimento semplice..
    mi spiego..

    quando scrivo
    codice:
    const string& Persona::getnome()const{
           return nome;
    }
    il programma compila, mentre quando levo il const iniziale no. Perchè? string nome non è costante.
    Possibile che quando metto il const iniziale significa che l'oggetto ritornato non è stato modificato e non come penso io che l'oggetto ritornato è costante?

    Scusate troppe domande lo so ahahhah
    Ultima modifica di MItaly; 15-01-2015 a 09:45 Motivo: Aggiunti tag CODE

  10. #10
    Quote Originariamente inviata da vicio_93 Visualizza il messaggio
    Va bene. Per ultimo quando per esempio invoco il costruttore di una classe base per una derivata se utilizzo gli stesso nomi posso avere un conflitto di nomi?

    es.
    codice:
    Persona::Persona(string a, string b, string c){...}
    
    Studente::Studente (string a, string b, string c, string d) : Persona (a,b,c){...}
    Perché dovrebbe dare problemi? È concettualmente equivalente a chiamare una normale funzione, le espressioni che passi come argomenti non c'entrano nulla con il nome dei parametri usati dentro la funzione.

    Quote Originariamente inviata da vicio_93 Visualizza il messaggio
    Poi quando compilo mi da un errore nella get dicendo che devo ritornare un riferimento a costante no un riferimento semplice..
    mi spiego..

    quando scrivo
    codice:
    const string& Persona::getnome()const{
           return nome;
    }
    il programma compila, mentre quando levo il const iniziale no. Perchè? string nome non è costante.
    Possibile che quando metto il const iniziale significa che l'oggetto ritornato non è stato modificato e non come penso io che l'oggetto ritornato è costante?

    Scusate troppe domande lo so ahahhah
    Se marchi un metodo come const, allora il this che ricevi è const, per cui tutti i membri "appaiono" come const. Per questo motivo non puoi restituire un riferimento non costante a nome, dato che this->nome in un metodo const è di tipo const std::string&.

    Per inciso, quando posti codice racchiudilo tra tag [CODE] ... [/CODE], altrimenti perde l'indentazione e non si attiva l'evidenziazione della sintassi (ora ho corretto io).
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.