Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Przyjaźń klas

Ostatnio zmodyfikowano 2016-09-08 22:32
Autor Wiadomość
latajacaryba
Temat założony przez niniejszego użytkownika
Przyjaźń klas
» 2016-09-06 22:35:10
Witam. Uczę się o przyjaźni klas i mam tu program. Dam jego bardzo okrojoną wersję, tylko niezbędne klasy.
plik.h
C/C++
#include <iostream>
using namespace std;
class Prostakat;
class Punkt
{
    friend class Prostakat;
    string nazwa;
    float x, y;
public:
    Punkt( string = "a", float = 0, float = 0 );
    void wczytaj();
};

class Prostakat
{
    friend class Punkt;
    string nazwa;
    float x, y, wysokosc, szerokosc;
public:
    Prostakat( string = "brak", float = 0, float = 0, float = 1, float = 1 );
    void wczytaj();
    void sedzia( Punkt pkt, Prostakat p );
};

// plik2.cpp

void sedzia( Punkt pkt, Prostakat p ) // Punkt i Prostakat to typy (nazwy klas). pkt i p to argumety formalne, nie aktualne wiec ich nazwa jest dowolna. operujemy nimi tylko w funkcji ;)
{
    if(( pkt.x >= p.x ) &&( pkt.x <=( p.x + p.szerokosc ) ) &&( pkt.y >= p.y ) &&( pkt.y <=( p.y + p.wysokosc ) ) )
         cout << endl << "punkt " << pkt.nazwa << " nalezy do prostokata.";
    else
         cout << endl << "punkt " << pkt.nazwa << " nie nalezy do prostokata.";
   
}

Wyszły 42 błędy, oczywiście wystarczy jedna zmiana, żeby wszystkie zniknęły bo wszystkie błędy tyczą się tego, że próbuję użyć w metodzie sedzia atrybutów prywatnych innej klasy. Ale ja zadeklarowałem przyjaźń, dlaczego więc nadal są takie błędy?
P-151512
carlosmay
» 2016-09-06 22:39:54
void sedzia( Punkt pkt, Prostakat p )
Bez kwalifikatora klasy, do której należy metoda, to zwykła funkcja.
Poza tym cross friend?
P-151513
latajacaryba
Temat założony przez niniejszego użytkownika
» 2016-09-06 22:53:46
Próbowałem, ale nie. Nie wiem jak. Mógłbyś powiedzieć gdzie co mam napisać, najlepiej wkleić błędną/ne linie i poprawić? Byłbym wdzięczny.
P-151515
carlosmay
» 2016-09-06 22:56:50
C/C++
void Prostakat::sedzia( Punkt pkt, Prostakat p ) // Punkt i Prostakat
Prostokąt
P-151517
latajacaryba
Temat założony przez niniejszego użytkownika
» 2016-09-06 23:07:40
tego też próbowałem, ale dalej nie działa :/
może podam jeszcze main
C/C++
int main()
{
    Punkt pkt1( "A", 3, 1 );
    Prostakat p1( "prostakat", 0, 0, 6, 4 );
    pkt1.wczytaj();
    p1.wczytaj();
    Prostakat sed;
    sed.sedzia( pkt1, p1 );
}

Poza tym czym różni się  void Prostakat::sedzia( Punkt pkt, Prostakat p )
od
void sedzia( Punkt pkt, Prostakat p )
skoro sedzia jest w klasie (w sensie jest w {} nawiasach klasy, czyli w środku)?

Na końcu podam jeszcze błędy

||=== Build: Debug in 2plik (compiler: GNU GCC Compiler) ===|
C:\Users\Pawel\Desktop\2plik\klasa.h|22|error: extra qualification 'Prostakat::' on member 'sedzia' [-fpermissive]|
C:\Users\Pawel\Desktop\2plik\klasa.h||In function 'void sedzia(Punkt, Prostakat)':|
C:\Users\Pawel\Desktop\2plik\klasa.h|8|error: 'float Punkt::x' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|18|error: 'float Prostakat::x' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|8|error: 'float Punkt::x' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|18|error: 'float Prostakat::x' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|18|error: 'float Prostakat::szerokosc' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|8|error: 'float Punkt::y' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|18|error: 'float Prostakat::y' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|8|error: 'float Punkt::y' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|18|error: 'float Prostakat::y' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|18|error: 'float Prostakat::wysokosc' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|39|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|7|error: 'std::string Punkt::nazwa' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|40|error: within this context|
C:\Users\Pawel\Desktop\2plik\klasa.h|7|error: 'std::string Punkt::nazwa' is private|
C:\Users\Pawel\Desktop\2plik\klasa.cpp|42|error: within this context|
||=== Build failed: 25 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|
P-151519
carlosmay
» 2016-09-06 23:17:51
Poza tym czym różni się  void Prostakat::sedzia( Punkt pkt, Prostakat p )
od
void sedzia( Punkt pkt, Prostakat p )
skoro sedzia jest w klasie (w sensie jest w {} nawiasach klasy, czyli w środku)?
Deklarując klasę, wszystko co jest w jej ciele (między {}) należy do klasy,
ale klasa ma swój zasięg (właśnie między tymi klamrami).
Masz dwa wyjścia, albo zdefiniować metodę między klamrami, lub
na zewnątrz dodając kwalifikator zasięgu danej klasy Prostakat:: inaczej
kompilator nie będzie szukał wewnątrz klamer, bo to nie jest zasięg
void sedzia
.

Ten kwalifikator miał być dodany do funkcji definiowanej na zewnątrz klasy, a nie w klasie.

C/C++
Punkt pkt1( "A", 3, 1 ); //
Prostakat p1( "prostakat", 0, 0, 6, 4 );
pkt1.wczytaj(); // nadpisujesz to co stworzyłeś konstruktorem, bez sensu
p1.wczytaj(); // to samo
Prostakat sed; // tutaj tworzysz nowy obiekt aby porównać dwa inne ?
sed.sedzia( pkt1, p1 );
Użycia klas nie rozumiesz.

C/C++
Punkt pkt1;
Prostakat p1;
pkt1.wczytaj();
p1.wczytaj();
p1.sedzia( pkt1, p1 ); // to też nie jest do końca dobrze, bo można przekazać tylko pkt1
p1.sedzia( pkt1 ); // p1 jest przekazany niejawnie jako *this (musiałbyś zmienić deklaracje metody)
P-151520
latajacaryba
Temat założony przez niniejszego użytkownika
» 2016-09-06 23:27:28
Już wiem! Niepotrzebnie w void Prostakat::sedzia(Punkt pkt,Prostakat p) ustalaliśmy zasięg, bo funkcja była W KLASIE pomiędzy {}
Poprawnie ma być tak:

C/C++
// plik naglowkowy

class Prostakat
{
    friend class Punkt;
    string nazwa;
    float x, y, wysokosc, szerokosc;
public:
    Prostakat( string = "brak", float = 0, float = 0, float = 1, float = 1 );
    void wczytaj();
    void sedzia( Punkt pkt, Prostakat p ); // bez operatora :: bo w klasie
   
};

//plik z funkcjami i metodami

void Prostakat::sedzia( Punkt pkt, Prostakat p ) // Punkt i Prostakat to typy (nazwy klas). pkt i p to argumety formalne, nie aktualne wiec ich nazwa jest dowolna. operujemy nimi tylko w funkcji ;)
{
    if(( pkt.x >= p.x ) &&( pkt.x <=( p.x + p.szerokosc ) ) &&( pkt.y >= p.y ) &&( pkt.y <=( p.y + p.wysokosc ) ) )
         cout << endl << "punkt " << pkt.nazwa << " nalezy do prostokata.";
    else
         cout << endl << "punkt " << pkt.nazwa << " nie nalezy do prostokata.";
   
}

// int main
Prostakat sed;
sed.sedzia( pkt1, p1 );
Dzięki za wskazówki ;). Ale mam jeszcze jedno pytanie. Funkcja (metoda) sedzia nic nie zwraca (void) wiec dlaczego muszę deklarować
Prostakat sed;
 i dopiero
sed.sedzia( pkt1, p1 );
Czy to po to, że gdyby istniały 2 funkcje o tych samych nazwach to kompilator nie wiedziałby o którą nam chodzi, a teraz wie "aha, obiekt klasy prostakat, w takim razie używam
funkcji z tej klasy (metody) o nazwie sedzia."?
P-151522
carlosmay
» 2016-09-06 23:32:14
C/C++
void Prostakat::sedzia( Punkt pkt ) // Punkt
{
    if(( pkt.x >= this->x ) &&( pkt.x <=( this->x + this->szerokosc ) ) &&( pkt.y >= this->y ) &&( pkt.y <=( this->y + this->wysokosc ) ) )
         cout << endl << "punkt " << pkt.nazwa << " nalezy do prostokata.";
    else
         cout << endl << "punkt " << pkt.nazwa << " nie nalezy do prostokata.";
   
}

// i wywołanie w main
int main()
{
    Prostakat p1;
    Punkt pkt1;
    p1.wczytaj();
    pkt1.wczytaj();
    p1.sedzia( pkt1 );
}

Czy to po to, że gdyby istniały 2 funkcje o tych samych nazwach to kompilator nie wiedziałby o którą nam chodzi, a teraz wie "aha, obiekt klasy prostakat, w takim razie używam
funkcji z tej klasy (metody) o nazwie sedzia."?
Tak to można rozumieć.
Jednak jeśli dwie lub więcej klas posiada część takich samych nazw metod i pól należy rozważyć użycie bazowej klasy abstrakcyjnej.
P-151523
« 1 » 2 3
  Strona 1 z 3 Następna strona