DOMANDA Codice C++ class friend non funziona

Dema.King84

Utente Attivo
506
57
C++:
#include <iostream>

using namespace std;


class Punto
{
public:
    int x;
    int y;

    Punto(void);
    void StampaDati(void);

private:

    int colore;

    friend void CambiaColore(int);

};

Punto::Punto(void)
{
    x=0;
    y=0;
    colore=0;
}

void Punto::StampaDati(void)
{
    cout<<"Ascisse:"<<x<<endl;
    cout<<"Ordinata:"<<y<<endl;
    cout<<"Colore:"<<colore<<endl;

}

 void CambiaColore(int c)
{
    Punto P;
    P.colore = c;
    P.StampaDati();
}

//errore fatale in p.colore = 3 is private within this context
int main()
{
    cout << "Le funzioni amiche :)" << endl;

    Punto P;
    P.colore = 3;
    P.StampaDati();
    return 0;
}


Osservando questo codice si nota subito che c'è un errore e purtroppo non so come risolverlo. Sicuramente sarà una banalità ma non ho ancora le capacità per arrivarci da solo.
chiedo a voi l' aiuto.
 

Andretti60

Utente Èlite
6,440
5,091
Scusa ma come fai a dire “si vede subito che c’è un errore” e poi non sai come risolverlo?
ci sono infatti due errori, il primo è che cerchi di accedere a una proprietà privata della classe (colore), il secondo è la implementazione del metodo CambiaColore, che essendo un friend come parametro deve avere referenze a oggetti della classe Punto
 
  • Haha
Reazioni: DispatchCode

Dema.King84

Utente Attivo
506
57
Scusa ma come fai a dire “si vede subito che c’è un errore” e poi non sai come risolverlo?
ci sono infatti due errori, il primo è che cerchi di accedere a una proprietà privata della classe (colore), il secondo è la implementazione del metodo CambiaColore, che essendo un friend come parametro deve avere referenze a oggetti della classe Punto
ho scritto che so che c'è un errore perchè non mi fa compilare il codice.
il fatto è che sto iniziando a studiare un libro per principianti ma è scritto da schifo e quello che si impara è poco.
per questo di tanto in tanto devo chiedere a chi ne sa. Sperando di avere interpretato bene quello che mi scrivi, mi sembra di capire che devo inserire dei dati nella superclasse nella sezione privata in modo tale che, tramite le funzioni, posso collegarmi alla parte pubblica della superclasse?
 

Andretti60

Utente Èlite
6,440
5,091
Di referenze in rete sulla parola chiave ‘friend’ ne trovi a palate, non ti devi soffermare su un testo solo. Perfino la pagina Wikipedia è molto chiara.

La dichiarazione del metodo cambiaColore dovrebbe essere così:
C:
friend CambiaColore(Punto& A, int c);
Ossia occorre passare al metodo la referenza della classe Punto a cui si vuole cambiare colore.

Piuttosto, quello che i testi scolastici dovrebbero insegnare è perché si introduca il concetto di friend, e in che circostanze conviene usarlo invece che un normale metodo pubblico di una classe. E soprattutto il pericolo che ne nasce, in quanto si rompe il concetto di incapsulazione (infatti in altri linguaggi OOP, tipo Java, non esiste)
 
  • Mi piace
Reazioni: Dema.King84

Dema.King84

Utente Attivo
506
57
sì, sicuramente un argomento da approfondire anche per la sua pericolosità. Più che altro da capire il suo concetto di base ma con un codice che si riesca a compilare sarebbe più facile la comprensione anche per via di un possibile debug.
Tornando a noi; sarebbe quindi possibile, secondo te, risolvere il problema con l' uso di un puntatore magari?
 

Dema.King84

Utente Attivo
506
57
il problema purtroppo rimane restituendomi sempre lo stesso errore. Come dicevo prima, la strada è ancora molto lunga e dovrò ancora trovare le informazioni documentandomi per risolvere l' applicazione della parola chiave Friend
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
il problema purtroppo rimane restituendomi sempre lo stesso errore. Come dicevo prima, la strada è ancora molto lunga e dovrò ancora trovare le informazioni documentandomi per risolvere l' applicazione della parola chiave Friend

Te l'ha praticamente scritto quello che devi fare, ti ha mostrato la firma... Con il riferimento passato dovrai modificare l'attributo colore, assegnandogli "c".
E in merito a friend, c'è la doc ufficiale: https://en.cppreference.com/w/cpp/language/friend
 

Dema.King84

Utente Attivo
506
57
C++:
#include <iostream>

using namespace std;


class Punto
{
public:
    int x;
    int y;

    Punto(void);
    void StampaDati(void);

private:

    int colore;

    friend void CambiaColore(Punto& A, int c);

};

Punto::Punto(void)
{
    x=0;
    y=0;
    colore=0;
}

void Punto::StampaDati(void)
{
    cout<<"Ascisse:"<<x<<endl;
    cout<<"Ordinata:"<<y<<endl;
    cout<<"Colore:"<<colore<<endl;

}

 void CambiaColore(int c)
{
    Punto P;
    P.colore = c;
    P.StampaDati();
}


int main()
{
    cout << "Le funzioni amiche :)" << endl;

    Punto P;
    P.colore = 3;
    P.StampaDati();
    return 0;
}
 

Allegati

  • error code.png
    error code.png
    21.2 KB · Visualizzazioni: 30

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Bhe, non basta cambiare la firma. Devi anche modificare l'implementazione ovviamente.
Ma il requisito fondamentale è capire cosa stai facendo però: a cosa serve e come usi il riferimento passato alla funzione?
 
  • Mi piace
Reazioni: Dema.King84

Dema.King84

Utente Attivo
506
57
Bhe, non basta cambiare la firma. Devi anche modificare l'implementazione ovviamente.
Ma il requisito fondamentale è capire cosa stai facendo però: a cosa serve e come usi il riferimento passato alla funzione?
ed è soprattutto questo quello che sto cercando di fare oltre che a risolvere.
Ci studierò su.
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Io ho l'impressione che non ti sono chiare anche altre cose, e non friend, che compresi gli altri concetti "base", non è così complesso.
Al link di prima trovi già la spiegazione in due righe:

The friend declaration appears in a class body and grants a function or another class access to private and protected members of the class where the friend declaration appears.

e sotto c'è un esempio che è praticamente come il tuo codice.

In buona sostanza la funzione che dichiari friend bypassa lo specificatore di accesso private e protected. Quindi, se p.colore è innaccessibile perchè è un membro privato, diventa accessibile all'interno di una funzione che ha la parola chiave friend.
 

Dema.King84

Utente Attivo
506
57
Io ho l'impressione che non ti sono chiare anche altre cose, e non friend, che compresi gli altri concetti "base", non è così complesso.
Al link di prima trovi già la spiegazione in due righe:



e sotto c'è un esempio che è praticamente come il tuo codice.

In buona sostanza la funzione che dichiari friend bypassa lo specificatore di accesso private e protected. Quindi, se p.colore è innaccessibile perchè è un membro privato, diventa accessibile all'interno di una funzione che ha la parola chiave friend.
sostanzialmente hai anche ragione.
Cioè, io ora sto studiando un libro che, pagina dopo pagina, mi sono accorto che spiega abbastanza male alcuni concetti: soprattutto quello di friend.
Di per sè è un concetto facile da capire e la base del concetto l' ho capita: friend "sprivatizza" un membro della classe privata per poterlo usare a livello globale. Quello che mi frega a me è capire come collegare i parametri della firma "sprivatizzata" con gli argomenti della funzione dove ci sono le istruzioni.

l' esempio di codice che mi stai dicendo l' ho già visto ma non è proprio simile al mio...qualcosa in più me l'ha fatta capire però c'è sempre quella cosa che mi sta sfuggendo ?
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Ma non c'è molto da "collegare" in verità. La firma della funzione ti dice quali parametri la tua funzione accetta, e qual è il tipo di ritorno (void, nel tuo caso).

Quindi se la firma è friend void CambiaColore(Punto &, int);, il corpo sarà semplicemente:

C++:
void CambiaColore(Punto &p, int c) {

}

per questo dicevo che secondo me non ti sono chiare altre cose; questo non ha nulla a che fare con "friend".
Riempi tu il corpo di questa funzione, e modifica anche il main per adattarlo (ovvero: chiama CambiaColore e poi StampaDati).
 
  • Mi piace
Reazioni: Dema.King84

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili