2010-07-22 9 views
12

Mi pregunta es respecto a las funciones de amigo, así como sobrecargar el < < y >>. Desde mi punto de vista, pensé que las funciones de un amigo podrían (y deberían) acceder directamente a las variables de los miembros privados. Sin embargo, en el caso que tengo aquí, el compilador solo aceptaría mi archivo .cxx cuando use las funciones "get" para obtener cada variable privada.C++ función de amigo - sobrecarga del operador istream >>

Aquí está mi archivo de cabecera

class BigNum 
public: 

// CONSTRUCTORS and DESTRUCTORS 
    BigNum();        
    BigNum(int num, size_t optional_base = 10);       
    BigNum(const char strin[], size_t optional_base = 10); 

// MEMBER FUNCTIONS 
    size_t get_digit(size_t index) const; 
    size_t get_used() const; 
    size_t get_capacity() const; 
    size_t get_base() const; 
    bool get_sign() const; 

// FRIEND FUNCTIONS 
    friend std::ostream& operator<<(std::ostream &os, const BigNum &bignum); 
    friend std::istream& operator>>(std::istream &is, BigNum &bignum); 

private: 
    size_t base;    
    size_t *digits;   
    bool positive;   
    size_t used;    

Aquí está mi archivo .cxx corresponde con las implementaciones para el amigo funciona

#include "file.h" 
#include <cstdlib> 
#include <iostream> 
#include <string> 
#include <cstring> 

using namespace std; 

std::ostream& operator <<(std::ostream &os, const BigNum &bignum) 
{ 
if (bignum.get_sign() == false) 
    os << '-'; 

for (size_t i = 0; i < bignum.get_used(); ++i) 
    os << bignum.get_digit(bignum.get_used() - i - 1); 

return os; 
} 

std::istream& operator >>(std::istream &is, BigNum &bignum) 
{ 
for (size_t i = 0; i < bignum.get_used(); ++i) 
    is >> bignum.digits[i]; 

return is; 
} 

Así que en este sentido los operadores amigo anteriores compilados correctamente. Sin embargo, ¿por qué mi operador >> puede acceder directamente a una variable privada (es >> bignum.digits [i]) pero el resto de las variables privadas deben recuperarse mediante 'get functions'

A continuación, cuando tratar de escribir los operadores de sobrecarga en este sentido (como yo pensaba funciones amigas deben llamar adecuadamente las variables privadas):

std::ostream& operator <<(std::ostream &os, const BigNum &bignum) 
{ 
if (bignum.positive == false) 
    os << '-'; 

for (size_t i = 0; i < bignum.used; ++i) 
    os << bignum.digits[used - i - 1]; 

return os; 
} 

std::istream& operator >>(std::istream &is, BigNum &bignum) 
{ 
for (size_t i = 0; i < bignum.used); ++i) 
    is >> bignum.digits[i]; 

return is; 
} 

obtengo los siguientes errores.

BigNum2.cxx: In function `std::ostream& 
    csci2270_hw1B::operator<<(std::ostream&, const csci2270_hw1B::BigNum&)': 
BigNum2.cxx:201: error: `used' undeclared (first use this function) 
BigNum2.cxx:201: error: (Each undeclared identifier is reported only once for 
    each function it appears in.) 
BigNum2.cxx: In function `std::istream& 
    csci2270_hw1B::operator>>(std::istream&, csci2270_hw1B::BigNum&)': 
BigNum2.cxx:208: error: syntax error before `)' token 

El compilador que estoy usando es g ++ (Versión 3.3.1). Cualquier ayuda se agradece, gracias.

Revisado:

He actualizado el código para que el objeto bignum podría tener acceso a las variables privadas. Hice lo siguiente al amigo operador sobrecargando < < y compiló bien. Gracias por los comentarios, ese fue un error de novato.

std::ostream& operator <<(std::ostream &os, const BigNum &bignum) 
{ 
if (bignum.positive == false) 
    os << '-'; 

for (size_t i = 0; i < bignum.used; ++i) 
    os << bignum.digits[bignum.used - i - 1]; 

return os; 
} 

errores Sin embargo, el compilador todavía se producen para el operador >>

BigNum2.cxx: En función std::istream& csci2270_hw1B::operator>>(std::istream&, csci2270_hw1B::BigNum&)': BigNum2.cxx:208: error: syntax error before)' símbolo

El >> se supone que es leído en un número y lo privado Se supone que la variable miembro 'utilizada' registra la longitud de la matriz. Todavía estoy un poco confundido sobre por qué el compilador acepta

std::istream& operator >>(std::istream &is, BigNum &bignum) 
{ 
for (size_t i = 0; i < bignum.get_used()); ++i) 
    is >> bignum.digits[i]; 

return is; 
} 

en contraposición a:

std::istream& operator >>(std::istream &is, BigNum &bignum) 
{ 
for (size_t i = 0; i < bignum.used); ++i) 
    is >> bignum.digits[i]; 

return is; 
} 

¿Alguna idea? Gracias.

+1

¿Qué es '" file.h "'? – GManNickG

Respuesta

9

Una función amigo tiene acceso a la clase datos privados, pero sí no obtener un puntero this para hacer que la automática, por lo que cada acceso a la clase de datos (privado o de otro tipo) tiene que ser calificado.Por ejemplo, esto:

os << bignum.digits[used - i - 1]; 

necesita ser:

os << bignum.digits[bignum.used - i - 1]; 
+0

gracias, que corrigió el << operador – user399415

5

No ha calificado used en la primera función - necesita ser bignum.used. Las sobrecargas del operador se definen en el alcance global, por lo que no obtienen un puntero this. Sin embargo, las funciones de amigo tienen acceso a los miembros privados de la clase.

std::ostream& operator <<(std::ostream &os, const BigNum &bignum) 
{ 
    if (bignum.positive == false) 
     os << '-'; 

    for (size_t i = 0; i < bignum.used; ++i) 
     // Note "bignum.used", instead of "used". 
     os << bignum.digits[bignum.used - i - 1];  
    return os; 
} 

std::istream& operator >>(std::istream &is, BigNum &bignum) 
{ 
    for (size_t i = 0; i < bignum.used; ++i) 
     is >> bignum.digits[i]; 

    return is; 
} 
2

Parece que hay un extra ')' en la siguiente línea justo después de bignum.used.

for (size_t i = 0; i < bignum.used**)**; ++i)