14

My question is in regards to friend functions as well as overloading the << and >>. From my understanding I thought friend functions could (and should) access private member variables directly. However in the case I have here the compiler would only accept my .cxx file when I used "get" functions to obtain each private variable.

Here is my header file

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; 

Here is my corresponding .cxx file with the implementations for the friend functions

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

So in this regard the above friend operators compiled correctly. However why is it that my operator >> can access one private variable directly (is >> bignum.digits[i]) but the rest of the private variables need to be retrieved by 'get functions'

Below, when I try to write the overload operators in this regard (how I thought friend functions should properly call private variables):

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

I obtain the following errors.

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 

The compiler I am using is g++ (Version 3.3.1). Any help is appreciated, thank you.

Revised:

I updated the code so the bignum object could access the private variables. I did the following to the friend operator overloading << and it compiled fine. Thanks for the comments, that was a rookie mistake.

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

However the compiler is still producing errors for the >> operator

BigNum2.cxx: In function std::istream& csci2270_hw1B::operator>>(std::istream&, csci2270_hw1B::BigNum&)': BigNum2.cxx:208: error: syntax error before)' token

The >> is supposed to read in a number and the private member variable 'used' is supposed to record the length of the array. I am still somewhat confused on why the compiler accepts

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 opposed to:

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

Any thoughts? thanks.

0

3 Answers 3

11

A friend function has access to the class' private data, but it does not get a this pointer to associate an invocation with a particular instance of the class, so every access to the class' data (private or otherwise) has to be qualified. For example this:

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

needs to be:

os << bignum.digits[bignum.used - i - 1]; 
Sign up to request clarification or add additional context in comments.

Comments

5

You haven't qualified used in the first function - it needs to be bignum.used. The operator overloads are defined at global scope, so they don't get a this pointer. However, the friend functions do have access to the private members of the class.

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

Comments

2

It seems there is an extra ')' in the following line right after bignum.used.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.