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.
A friend function has access to the class' private data, but it does not get a
this
pointer to make that automatic, so every access to the class' data (private or otherwise) has to be qualified. For example this:needs to be:
It seems there is an extra ')' in the following line right after bignum.used.
You haven't qualified
used
in the first function - it needs to bebignum.used
. The operator overloads are defined at global scope, so they don't get athis
pointer. However, the friend functions do have access to the private members of the class.