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

[C++] Zaprzyjaźnianie przeciążonego operatora z klasą std::ostream

Ostatnio zmodyfikowano 2013-06-18 14:38
Autor Wiadomość
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:
C/C++
#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:
C/C++
#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:
C/C++
#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";
    //cout << "-- "<<v._m_rozmiar;
   
    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
P-85774
Monika90
» 2013-06-18 08:41:56
Dodaj #include <ostream> do pliku wektor.h
P-85776
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?
P-85777
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:
C/C++
int zmienna = v._m_rozmiar; //Tu będzie błąd
std::cout << zmienna;
P-85779
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 :)
P-85782
DejaVu
» 2013-06-18 14:38:17
No to temat zamykam, skoro problem rozwiązałeś :)
P-85783
« 1 »
  Strona 1 z 1