[C++] Zaprzyjaźnianie przeciążonego operatora z klasą std::ostream
Ostatnio zmodyfikowano 2013-06-18 14:38
johny Temat założony przez niniejszego użytkownika  | 
[C++] Zaprzyjaźnianie przeciążonego operatora z klasą std::ostream » 2013-06-18 01:47:14 Witam. Mam problem z zaprzyjaźnieniem, a następnie implementacją przeciążonego operatora <<, który ma później posłużyć do wypisywania składowych prywatnych klasy Wektor. Konkretnie chodzi o linijki 
 
friend std::ostream& operator<<(std::ostream &, Wektor const &); //czyli piąta w pliku .h i
 std::ostream& operator<<(std::ostream &F, Wektor const &w){
           return << w._m_rozmiar;
      }
 czyli ostatnie w pliku .cpp. Próbowałem kombinować z przestrzeniami nazw, ale nie potrafię znaleźć rozwiązania, żeby kod się kompilował.
 Wektor.h:
 #include <cstdlib>
  class Wektor {     friend std::ostream & operator <<( std::ostream &, Wektor const & );     size_t _m_rozmiar;     int * _m_ptab; public:          Wektor( size_t n )         : _m_rozmiar( n )         , _m_ptab( new int[ n ] )     { }     Wektor( Wektor const & w );     ~Wektor() { delete[] _m_ptab; }          void operator =( Wektor const & w );          size_t size() { return _m_rozmiar; }     int & at( int n ) { return _m_ptab[ n ]; }     int & at( int n ) const { return _m_ptab[ n ]; } }; 
Wektor.cpp:
 #include "Wektor.h"
  Wektor::Wektor( Wektor const & w )     : _m_rozmiar( w._m_rozmiar )     , _m_ptab( new int[ w._m_rozmiar ] ) {     for( size_t i = 0; i < _m_rozmiar; i++ )          _m_ptab[ i ] = _m_ptab[ i ];      }
  void Wektor::operator =( Wektor const & w ) {     if( this ==& w )          return;          if( this->_m_rozmiar != w._m_rozmiar ) {         delete[] this->_m_ptab;         this->_m_rozmiar = w._m_rozmiar;         this->_m_ptab = new int[ _m_rozmiar ];     }     for( int i = 0; i < _m_rozmiar; i++ )          this->_m_ptab[ i ] = w._m_ptab[ i ];      }
  std::ostream & operator <<( std::ostream & F, Wektor const & w ) {     return << w._m_rozmiar; }
  
main.cpp:
 #include <cstdlib> #include <iostream> #include "Wektor.h"
  using namespace std;
  int main( int argc, char * argv[] ) {     Wektor v( 5 );     Wektor w( 20 );     v = w;          v.at( 5 ) = 1;     v.at( 3 ) = 41;     cout << "rozmiar wektora v= " << v.size()     << ", wartosc elementu 5= " << v.at( 3 ) << "\n\n";               system( "PAUSE" );     return EXIT_SUCCESS; }  
Oto co myśli na ten temat kompilator:
 Kompilator: Default compiler
 Building Makefile: "D:\Programy\Dev-Cpp\Makefile.win"
 Wykonywanie  make clean
 rm -f main.o Wektor.o  Projekt1.exe
 
 g++.exe -c main.cpp -o main.o -I"D:/Programy/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2/backward"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2"  -I"D:/Programy/Dev-Cpp/include"   
 
 g++.exe -c Wektor.cpp -o Wektor.o -I"D:/Programy/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2/backward"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2"  -I"D:/Programy/Dev-Cpp/include"   
 
 In file included from Wektor.cpp:1:
 Wektor.h:5: error: ISO C++ forbids declaration of `ostream' with no type
 Wektor.h:5: error: `ostream' is neither function nor member function; cannot be declared friend
 
 Wektor.h:5: error: expected `;' before '&' token
 Wektor.cpp:21: error: expected constructor, destructor, or type conversion before '&' token
 Wektor.cpp:21: error: expected `,' or `;' before '&' token
 
 make.exe: *** [Wektor.o] Error 1
 
 Wykonanie zakończone  | 
 | 
Monika90  | 
» 2013-06-18 08:41:56 Dodaj #include <ostream> do pliku wektor.h  | 
 | 
johny Temat założony przez niniejszego użytkownika  | 
» 2013-06-18 11:39:31 No racja, nie popisałem się, taki błąd. Dodatkowo również linijka: return << w._m_rozmiar; została zamieniona na: return F << w._m_rozmiar; bo wcześniej gdzieś tam zjadłem F. I znowu doszedłem do momentu, w którym po odkomentowaniu w pliku main.cpp linijki: cout << "-- " << v._m_rozmiar; kompilator wywala takie coś: Kompilator: Default compiler Building Makefile: "D:\Programy\Dev-Cpp\Makefile.win" Wykonywanie  make clean rm -f main.o Wektor.o  Projekt1.exe
  g++.exe -c main.cpp -o main.o -I"D:/Programy/Dev-Cpp/lib/gcc/mingw32/3.4.2/include"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2/backward"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2/mingw32"  -I"D:/Programy/Dev-Cpp/include/c++/3.4.2"  -I"D:/Programy/Dev-Cpp/include"   
  Wektor.h: In function `int main(int, char**)':
  Wektor.h:7: error: `size_t Wektor::_m_rozmiar' is private main.cpp:17: error: within this context
  make.exe: *** [main.o] Error 1
  Wykonanie zakończone W sumie dopiero tutaj pojawia się to właściwe pytanie, które chciałem zadać. Pola _m_rozmiar dalej nie można wyplotować, przy użyciu cout<< w mainie. Dlaczego?  | 
 | 
DejaVu  | 
» 2013-06-18 13:03:19 Wektor.h:7: error: `size_t Wektor::_m_rozmiar' is private
 main.cpp:17: error: within this context
  
 W sumie dopiero tutaj pojawia się to właściwe pytanie, które chciałem zadać.
 Pola _m_rozmiar dalej nie można wyplotować, przy użyciu cout<< w mainie. Dlaczego?
  |  
 
Ponieważ _m_rozmiar jest składową prywatną, a Ty próbujesz uzyskać do niej dostęp spoza klasy. To tak jak byś próbował zrobić coś takiego:
 int zmienna = v._m_rozmiar;  std::cout << zmienna;
   | 
 | 
johny Temat założony przez niniejszego użytkownika  | 
» 2013-06-18 14:09:00 Właśnie dlatego zaprzyjaźniam przeciążony operator '<<'. Żeby uzyskać dostęp do składowych prywatnych. Z tego co rozumiem słowo kluczowe friend informuje kompilator, które funkcje mają mieć dostęp do składowych prywatnych. Dobra, już wiem co robiłem nie tak. Błąd był w main, przy wywoływaniu operatora. cout << "-- " << v._m_rozmiar;  było cout << "-- " << v;  powinno być W ten sposób uzyskuję dostęp do pola prywatnego poza obrębem klasy. Dziękuję Wam za pomoc :)  | 
 | 
DejaVu  | 
» 2013-06-18 14:38:17 No to temat zamykam, skoro problem rozwiązałeś :)  | 
 | 
|  « 1 »  |