2010-07-22 2 views
12

내 질문은 친구 기능과 관련되어 있으며 < < 및 >> 과부하와 관련이 있습니다. 필자는 친구 함수가 private 멤버 변수에 직접 액세스 할 수 있어야한다고 생각했습니다. 그러나 여기에있는 경우 컴파일러는 각 개인 변수를 얻기 위해 "get"함수를 사용할 때만 .cxx 파일을 허용합니다.C++ friend 함수 - 연산자 오버로드 istream >>

가 여기 내 헤더 파일을 여기에

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;    

입니다 친구에 대한 구현과 내 해당 .CXX 파일은 위의 친구 사업자가 제대로 컴파일이 점에서

#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; 
} 

그래서 작동합니다. 그러나 왜 내 operator >>가 하나의 private 변수에 직접 액세스 할 수 있습니까 (>> bignum.digits [i]). 그러나 나머지 private 변수는 'get functions'에 의해 검색되어야합니다.

아래에서 (나는 친구 기능이 제대로 private 변수를 호출해야한다고 생각하는 방법)이 점에서 과부하 운영자를 작성하려고 : 나는 다음과 같은 오류를 얻을

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; 
} 

합니다.

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 

사용하는 컴파일러는 g ++ (버전 3.3.1)입니다. 도움이된다면 고맙습니다.

는 개정 된 다음의 bignum 객체가 private 변수에 액세스 할 수 있도록

나는 코드를 업데이트했습니다. 나는 친구 오퍼레이터에게 다음을 수행하여 < <을 오버로딩하고 잘 컴파일했다. 의견을 주셔서 감사합니다, 그것은 신참 실수였습니다. >> 연산자

BigNum2.cxx위한

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; 
} 

그러나 컴파일러 여전히 생산 오류 : 토큰 기능 std::istream& csci2270_hw1B::operator>>(std::istream&, csci2270_hw1B::BigNum&)': BigNum2.cxx:208: error: syntax error before) '

을 >> 등록 번호는 개인 판독하도록되어 멤버 변수 'used'는 배열의 길이를 기록합니다.

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

return is; 
} 

어떤 생각 : 반대로 나는 아직도 컴파일러가

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

return is; 
} 

을 수락 이유에 다소 혼란 스러워요? 감사.

+1

"file.h"란 무엇입니까? – GManNickG

답변

9

친구 기능은 클래스에 액세스 할 수있다 '개인 데이터를하지만 클래스에 그 자동, 그래서 모든 액세스를 확인하기 위해 this 포인터를하지 않는'데이터 (그렇지 않으면 개인 또는를)이어야한다 자격 있는.예를 들어이 들어 :

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

필요가되게합니다 : 다음 줄에 ')'추가를 잘 작성 후 bignum.used이 보인다

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

덕분에 << 연산자를 수정했습니다. – user399415

5

첫 번째 기능으로 used을 인증하지 않았습니다. bignum.used이어야합니다. 연산자 오버로드는 전역 범위에서 정의되므로 포인터가 this이 아닙니다. 그러나 friend 함수는 클래스의 private 멤버에 액세스 할 수 있습니다.

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

.

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