Funkcje zaprzyjaźnione - Definicja w innej klasie?

0

Witam. Mam zadanie, w którym mam skorzystać z funkcji zaprzyjaźnionych. Problem polega na tym, że gdy chcę napisać funkcję zaprzyjaźnioną do jednej klasy w innej klasie, to kompilator twierdzi, że nie ma dostępu do składowych tej pierwszej klasy. Używam Visual Studio 2012. Oto prosty kod wzięty z internetu żeby przedstawić problem:
Tutaj działa:

#include <iostream>
    using namespace std;
     
    class klasa
    {
      int liczba; // wiadomo, że standardowo składowe klasy są prywatne
      public:
        friend void wyswietl(klasa&);  // deklaracja funkcji zaprzyjaźnionej
    };
     
     
     
            void wyswietl(klasa& kl)
            {
                    cout << "liczba z klasy to: " << kl.liczba << endl;
            }
     
            int main()
            {
                    klasa kla;
                    wyswietl(kla);
                    system("pause");
                    return 0;
                   
            };

Tutaj nie działa (Pokazuje, że nie ma dostępu do kl.liczba w klasie Main):

    #include <iostream>
    using namespace std;
     
    class Main;
    class klasa
    {
      int liczba; // wiadomo, że standardowo składowe klasy są prywatne
      public:
        friend void wyswietl(klasa&);  // deklaracja funkcji zaprzyjaźnionej
    };
     
     
    class Main
    {
            void wyswietl(klasa& kl)
            {
                    cout << "liczba z klasy to: " << kl.liczba << endl;
            }
     
            int main()
            {
                    klasa kla;
                    wyswietl(kla);
                    system("pause");
                    return 0;
                   
            }
    };

0

Wg mnie nie można tak zaprzyjaźniać. W takim przypadku należy zaprzyjaźnić całą klasę Main z klasą klasa.

0

friend void Main::wyswietl(klasa&);

#include <iostream>
using namespace std;
 
class klasa;
class Main
  {
   public:
   void wyswietl(klasa& kl);
  };
    
class klasa
  {
   int liczba; // wiadomo, że standardowo składowe klasy są prywatne
   public:
   friend void Main::wyswietl(klasa&);  // deklaracja funkcji zaprzyjaźnionej
  };

void Main::wyswietl(klasa& kl)
  {
   cout << "liczba z klasy to: " << kl.liczba << endl;
  }

int main()
  {
   Main m;
   klasa kla;
   m.wyswietl(kla);
   return 0;
  }

http://ideone.com/EF1ZiI

0

A da się to podzielić na pliki? Bo ja zrobiłem tak:
Plik klasa.h:

class klasa
  {
   int liczba; // wiadomo, że standardowo składowe klasy są prywatne
   public:
   friend void Main::wyswietl(klasa&);  // deklaracja funkcji zaprzyjaźnionej
  }; 

Plik Main.h:

#include "klasa.h"

class klasa;
class Main
  {
   public:
   void wyswietl(klasa& kl);
  };

Plik Main.cpp:

#include <iostream>
#include "Main.h"
using namespace std;

void Main::wyswietl(klasa& kl)
  {
   cout << "liczba z klasy to: " << kl.liczba << endl;
  }
 
int main()
  {
   Main m;
   klasa kla;
   m.wyswietl(kla);
   return 0;
  } 

i mam komunikat "'Main' : is not a class or namespace name", a poza tym wtedy znów nie ma dostępu do kl.liczba.

0

A nie widzisz w klasa.h odwołania się do Main ?
A nie wiesz że trzeba dokładać #pragma once lub inne zabezpieczenia przed powtórnym dołączeniem?

0

Może i można, ale to niemądre. Albo friend class albo wcale.

0

Próbowałem kombinować, ale nadal różne błędy są, więc byłbym wdzięczny za pokazanie dokładnie jak to napisać. O pragma once słyszę po raz pierwszy, właściwie jestem początkujący w c++.
Edit: Może faktycznie najlepiej by było użyć klas zaprzyjaźnionych, bo to akurat działa bez problemu, tylko nie jestem pewny czy mi to uznają na studiach.

0

MainClass.h

#ifndef MAIN_CLASS_H
#define MAIN_CLASS_H

class klasa;
class Main
  {
   public:
   void wyswietl(klasa& kl);
  };

#endif

KlasaClass.h

#ifndef KLASA_CLASS_H
#define KLASA_CLASS_H
#include "MainClass.h"

class klasa
  {
   int liczba;
   public:
   friend void Main::wyswietl(klasa&);
  };

#endif

MainClass.cpp

#include <iostream>
#include "KlasaClass.h"
#include "MainClass.h"

void Main::wyswietl(klasa& kl)
  {
   std::cout << "liczba z klasy to: " << kl.liczba << std::endl;
  }

main.cpp

#include <iostream>
#include "KlasaClass.h"
#include "MainClass.h"
using namespace std;
 
int main()
  {
   Main m;
   klasa kla;
   m.wyswietl(kla);
   return 0;
  }

1 użytkowników online, w tym zalogowanych: 0, gości: 1