Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1

    [c++] condividere puntatore

    codice:
    class Plate {
        Materiale* p_materiale;
        ....
        CLS cls = CLS(Rck);
        p_materiale = &cls;
        ...
        public friend bool verificaPLATE(Plate& p);
    };
    bool verificaPLATE(Plate& p) {
    ...
    Rettangolare X = Rettangolare(X,H,p.p_materiale); //non riconosce il costruttore..perchè?
    verifica(X); //vedi più avanti
    ...
    }
    
    class Sezione {
        protected Materiale * p_materiale; 
        ...
    };
    
    class Rettangolare : public Sezione {
        public Rettangolare(...,Materiale * p) {
            p_materiale = p;
        }
        public friend bool verifica(Rettangolare& s);
    };
    
    bool verifica(Rettangolare& s) {
        //QUI errore se richiamo p_materiale.funzione();
    }
    
    class Materiale {...};
    class CLS : public Materiale {..};
    perchè non passa il puntatore?

  2. #2
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    codice:
    class Plate {
        Materiale* p_materiale;
        ....
        CLS cls = CLS(Rck);
        p_materiale = &cls;
        ...
        public friend bool verificaPLATE(Plate& p);
    };
    p_materiale è un membro pubblico o privato ?

  3. #3
    Originariamente inviato da ramy89
    p_materiale è un membro pubblico o privato ?
    privato...

    è un problema?

  4. #4
    Originariamente inviato da zannas
    privato...

    è un problema?
    Be', il punto dei membri privati è proprio di non essere accessibili dall'esterno della classe... Se lo vuoi vedere dall'esterno o lo rendi pubblico o crei un getter pubblico.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    mmm.. ho modificato un pò il codice per aggirare il problema, ora comunque continuo a non riuscire a passare un oggetto:

    codice:
    SezRettangolare sezX = SezRettangolare(get_x(),get_h(),cls);
    la classe è definita come:
    codice:
    SezRettangolare(double& base, double& altezza, CLS& cls) {..}
    get_x() e get_h() mi restituiscono un double e cls è un oggetto della classe CLS.

    L'errore che mi riporta il compilatore è:

    error: no matching function for call to 'SezRettangolare::SezRettangolare(double, double, CLS& ) '

    Vi ringrazio in anticipo per la mano che mi state dando, ma sono un novello autodidatta in C++ per un progetto da fare all'uni e ovviamente C++ ci han detto che esiste, per impararlo: Arrangiarsi...

  6. #6
    get_x e get_y restituiscono un double (e non un riferimento a double), per cui stai passando un rvalue ad un costruttore che si aspetta due riferimenti non costanti a double (che quindi devono essere degli lvalue).
    Per risolvere:
    - o cambi il costruttore in modo che accetti dei normali double invece che dei riferimenti a double (cosa più sensata, perché il costruttore dovrebbe ricevere quei double per riferimento?)
    - o lo cambi in modo che accetti dei const double & (i riferiment const possono riferirsi a degli rvalue) (ma non ha molto senso).

    ... ma come vedi il C++ è un linguaggio piuttosto complicato, arrangiarsi in qualche maniera è la maniera peggiore possibile di impararlo.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Originariamente inviato da MItaly
    get_x e get_y restituiscono un double (e non un riferimento a double), per cui stai passando un rvalue ad un costruttore che si aspetta due riferimenti non costanti a double (che quindi devono essere degli lvalue).
    Per risolvere:
    - o cambi il costruttore in modo che accetti dei normali double invece che dei riferimenti a double (cosa più sensata, perché il costruttore dovrebbe ricevere quei double per riferimento?)
    - o lo cambi in modo che accetti dei const double & (i riferiment const possono riferirsi a degli rvalue) (ma non ha molto senso).

    ... ma come vedi il C++ è un linguaggio piuttosto complicato, arrangiarsi in qualche maniera è la maniera peggiore possibile di impararlo.
    grazie, ma scusa l'ignoranza.... che roba sono gli lvalue e rvalue?
    La seconda immagino stia per reference value... l'altra?

  8. #8
    Per dirla in maniera rozza, sono i valori che in un assegnamento (L=R) possono stare rispettivamente a sinistra (lvalue - left-value) e destra (rvalue - right-value) del segno di uguale.
    (naturalmente un lvalue può anche stare a destra, ma non viceversa)

    I literal (=i valori inseriti direttamente nel codice) sono ovviamente degli rvalue, sia per ragioni di senso (che senso avrebbe scrivere 5=a?) che per ragioni di codice generato (in genere i literal sono inseriti direttamente nell'assembly generato come valori immediate); idem i valori restituiti dalle funzioni per valore (non ha senso ad esempio scrivere
    codice:
    int funzione()
    {
        return 10;
    }
    
    // ...
    funzione()=5;
    )
    I reference invece sono degli lvalue, perché "nascondono" dietro un indirizzo di memoria in cui vanno a memorizzare quello che ci viene assegnato:
    codice:
    int a;
    
    int & funzione()
    {
        return a;
    }
    
    // ...
    funzione() = 10; // 10 va a finire in a, dato che funzione() ha restituito un reference ad a
    motivo per cui degli lvalue si può ottenere l'indirizzo con l'operatore &, mentre degli rvalue no.

    Dato che i reference sono degli lvalue per definizione, li si può inizializzare solo con degli rvalue (ricorda che un reference è un alias per ciò a cui viene inizializzato), altrimenti la semantica del linguaggio andrebbe all'aria.
    codice:
    int & funzione()
    {
        return 5; // <-- qui ottieni un errore di compilazione, stai inizializzando il reference restituito con un lvalue
    }
    
    funzione()=10; // che cavolo mi vorrebbe significare? Dove verrebbe copiato questo 10?
    Eccezione: i const reference; dato che un const reference (ad esempio const int & ) non può essere destinatario di un assegnamento, il problema di cui sopra non si pone, per cui un const & può essere inizializzato con un lvalue (e quindi con un literal o con un temporary):
    codice:
    int funzione()
    {
        return 5;
    }
    
    void funzione2(const int & a)
    {
        // a è const, per cui non ci posso assegnare nulla, dunque può riferirsi "nascostamente" ad un lvalue
    }
    
    funzione2(funzione()); // no problem, il valore restituito è un lvalue ma funzione2 accetta un const int &
    funzione2(5); // idem
    In questo esempio il compilatore probabilmente farà un push sullo stack del valore restituito da funzione o del literal e ne passerà l'indirizzo "dentro il reference" a funzione2.

    Nota che un const reference in realtà è un oggetto strano, perché non può stare a sinistra di un assegnamento, ma essendo un reference di fatto avrà un indirizzo nascosto dietro. Per questo motivo la terminologia lvalue/rvalue è incompleta, e si parla talvolta di modifiable/nonmodifiable lvalue per distinguere gli lvalue "normali" dai const reference.
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    se volevi spaventarmi ci sei riuscito benissimo
    ahahah no dai.. purtroppo vedo ben di peggio

    allora, approfittando della tua cortesia chiedo:
    A uno che non interessano (seppur siano interessanti) troppi fronzoli "specialistici" ma che guarda al risultato e che comunque questo deve essere un buon risultato, e cioè intendo una buona programmazione di medio livello, come consigli il passaggio di valori/oggetti/variabili/qualsiasicosa attraverso funzioni/membri ecc ?
    Attraverso:

    funzione(tipo1 nome, tipo2 nome2, ...) {}
    funzione(tipo1& nome, tipo2& nome2, ...){}
    funzione(tipo1 * nome, tipo2 * nome2, ....){}

    Quale ritieni tra queste forme la migliore tenendo conto:
    qualità di programmazione, possibilità di errore, gestione memoria, velocità nel ritrovare eventuali errori, pulizia codice e tutte un sacco di miriadi di altre cose/problematiche che io non conosco e tu sicuramente conoscerai?

  10. #10
    Originariamente inviato da zannas
    funzione(tipo1 nome, tipo2 nome2, ...) {}
    funzione(tipo1& nome, tipo2& nome2, ...){}
    funzione(tipo1 * nome, tipo2 * nome2, ....){}

    Quale ritieni tra queste forme la migliore
    Dipende.
    Se tutto ciò che ti serve è passare un valore ad una funzione, senza che le modifiche fatte dalla funzione si ripercuotano all'esterno usa
    - passaggio per valore per i tipi primitivi
    - passaggio per const reference per struct e classi. Attenzione però che le classi dovranno essere scritte in maniera adeguata per funzionare con oggetti const (ad esempio, tutti i membri che non modificano lo stato interno dell'oggetto devono essere dichiarati come const).
    Il passaggio per valore per classi/struct può avere senso se si tratta di classi "piccole" come dimensioni e con costruttore di copie relativamente leggero, e soprattutto se all'interno della funzione necessiti di modificare una copia dell'oggetto passato.

    Se invece vuoi che le modifiche si vedano all'esterno usa sempre i reference.

    I puntatori riservali solo a casi particolari, ad esempio quando vuoi passare un array stile C (cosa che in genere eviterei, preferendo std::vector & co.), accompagnandolo sempre con le sue dimensioni portate in un parametro size_t; se l'array non viene modificato dentro la funzione una un puntatore const.
    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 © 2024 vBulletin Solutions, Inc. All rights reserved.