Archived

This topic is now archived and is closed to further replies.

Friends & overloading output

This topic is 5126 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m attempting to write an output function for a class, but the compiler doesn''t like it. The relevant code:
#include <iostream>
using namespace std;

#define MONEY_TYPE long int

class money {
	public:
		friend ostream& operator << (ostream&, money&);
}


ostream& operator << (ostream& out, money& output) {
	out << (float(output.amount)/100);
	return out;
}
The compiler tells me that the function cannot access the private variable "amount". Shouldn''t that be solved by making the declaration include the word "friend?"

Share this post


Link to post
Share on other sites
friend functions arent my calling (only gone through comp science 110) but im pretty sure that it needs to be a friend function of your output struct, o wait, u seem to have done that, maybe u need the friend identifier thingy when u actually define the function? just a thought

Share this post


Link to post
Share on other sites
your code compiles fine once the syntax errors are fixed. I suggest you post the full actual code, since that doesn''t seem to be it.

Also note that your insertion function should really take a const reference to a money, not a mutable reference. This will allow it to work with unnamed temporary variables as well as operate correctly on const objects. This probably isn''t causing the error you''re getting, though.


"Sneftel is correct, if rather vulgar." --Flarelocke

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Maybe if you made the function private instead of public, just a thought, not sure if it changes anything.

Share this post


Link to post
Share on other sites
dont think that would help at all, that would just make if so that the function could only be called from that class ex. from another of it''s member functions (at least thats my understanding at least)

Share this post


Link to post
Share on other sites
Allright, full code:


//money.h


#include <iostream>
using namespace std;

#define MONEY_TYPE long int



class money {
private:
MONEY_TYPE amount;
public:
money();
money(float);
money(int);
money(money&);
~money();
money& operator = (float);
money& operator = (int);
money& operator = (const money&);
bool operator < (const money&);
bool operator > (const money&);
bool operator == (const money&);
float operator + (const money&);
float operator + (int);
float operator + (float);
float operator - (const money&);
float operator - (int);
float operator - (float);
float operator * (int);
float operator * (float);
float operator / (int);
float operator / (float);
friend ostream& operator << (ostream&, const money&);
istream& operator >> (istream&);
};



//money.cpp


#include "money.h"


money::money() {
amount = 0;
}


money::money(float input) {
amount = (int)(input * 100);
}


money::money(int input) {
amount = input * 100;
}


money::money(money& other_money) {
amount = other_money.amount;
}


money::~money() {
//no pointers, so it's okay

}


money& money::operator = (float input) {
float temp;
temp = input * 100;
amount = (MONEY_TYPE)(temp);
return *this;
}


money& money::operator = (int input) {
amount = input * 100;
return *this;
}


money& money::operator = (const money& other_money) {
amount = other_money.amount;
return *this;
}


bool money::operator < (const money& right_money) {
if (amount < right_money.amount)
return true;
return false;
}


bool money::operator > (const money& right_money) {
if (amount > right_money.amount)
return true;
return false;
}


bool money::operator == (const money& right_money) {
if (amount == right_money.amount)
return true;
return false;
}


float money::operator + (const money& right_money) {
MONEY_TYPE temporary;
temporary = amount + right_money.amount;
return ((float)temporary / 100);
}


float money::operator + (int input) {
MONEY_TYPE temporary;
temporary = amount + (input * 100);
return ((float)temporary / 100);
}


float money::operator + (float input) {
MONEY_TYPE temporary;
temporary = amount + MONEY_TYPE(input * 100);
return ((float)temporary / 100);
}


float money::operator - (const money& right_money) {
MONEY_TYPE temporary;
temporary = amount - right_money.amount;
return ((float)temporary / 100);
}


float money::operator - (int input) {
MONEY_TYPE temporary;
temporary = amount - (input * 100);
return ((float)temporary / 100);
}


float money::operator - (float input) {
MONEY_TYPE temporary;
temporary = amount - MONEY_TYPE(input * 100);
return ((float)temporary / 100);
}


float money::operator * (int input) {
MONEY_TYPE temporary;
temporary = amount * input;
return ((float)temporary / 100);
}


float money::operator * (float input) {
MONEY_TYPE temporary;
temporary = MONEY_TYPE(amount * input);
return ((float)temporary / 100);
}

float money::operator / (int input) {
MONEY_TYPE temporary;
temporary = amount / input;
return ((float)temporary / 100);
}

float money::operator / (float input) {
MONEY_TYPE temporary;
temporary = MONEY_TYPE(amount / input);
return ((float)temporary / 100);
}

ostream& operator << (ostream& out, const money& output) {
out << (float(output.amount)/100);
return out;
}


istream& money::operator >> (istream& in) {
double input;
in >> input;
amount = MONEY_TYPE(input * 100);
return in;
}


Most of that has no application to the problem, but there it is. Thanks for pointing out that the reference was mutable, I had missed that one. I also wasn't aware that it would affect unnamed temporary variables. Thanks for the help so far!

[edited by - idhrendur on December 1, 2003 3:23:14 PM]

Share this post


Link to post
Share on other sites
Ok, maybe I'm not entirely sure what your trying to accomplish but, It looks to me like you want the << operator to be overloaded for your money class, not a global overloaded operator. If thats the case, then removing the friend keyword, and changing

ostream& operator << (ostream& out, const money& output) { out << (float(output.amount)/100); return out;
}

to

ostream& money::operator << (ostream& out, const money& output) { out << (float(output.amount)/100); return out;
}

will solve your problem of accessing a private member var.

Or, if that was what you were trying to accomplish, you need to add a Get and possibly Set accessor function to your class. For example:

const MONEY_TYPE& GetAmount() const { return amount; }


[edited by - pjcast on December 1, 2003 3:36:55 PM]

Share this post


Link to post
Share on other sites
in the money class, put the variable amount protected like this:

class money
{
public:
friend ostream& operator << (ostream &out, money &output);
protected:
long int amount;
// [...]

};

friend ostream& operator << (ostream &out, money &output);
{
// now you will be able to use output.amount

//[...]

}

hope that helps
Matt

[edited by - lemurion on December 1, 2003 3:39:25 PM]

Share this post


Link to post
Share on other sites
I was attempting to just overload it for the money class (I think). The problem with that solution is that I have another class using money as a basic type, and when it tries to output the money type, the compiler becomes convinced I have no << operator which takes a type money on the right-hand side. (I appologize for the grammer of that sentence. Ugh!)

The second solution would work just fine, but isn't the point of the friend keyword to provide access to private data as if the friend function actually were part of the class. Have my books and instructors expalined this incorrectly to me?

Thanks again for the help. Soon, I will be done with this stupid (college) class and on to more advanced ones (Meaning you will probably get to know me well in the spring)

[edited by - idhrendur on December 1, 2003 3:59:42 PM]

Share this post


Link to post
Share on other sites
I rarely use the friend keyword, but it should provide access to all members of a class (private, public, or protected), because the friend keyword basically makes that fucntion like any other class member function with regards to member access. I found an article which is basically what you are trying to accomplish, http://www.icce.rug.nl/documents/cplusplus/cplusplus11.html

Hope this can help you

[edited by - pjcast on December 1, 2003 4:05:57 PM]

Share this post


Link to post
Share on other sites
Curses! The only difference I could see from the article implementation was some minor syntax stuff (use of white space). For the heck of it, I changed mine to match theirs, and it made no difference. As far as I can tell, from all accounts, this should work, and yet it doesn''t. Does this compile fine on your systems?

I suppose I should just drop my pride soon and just put in the access functions for the internal variable...ah well.

Share this post


Link to post
Share on other sites
Yep. Apparently Visual C++ assumes that if a function is a frend, then it is also inline. Once I formatted the functions as if they were inline, then it worked just fine.

Thanks for the help, everybody!

[edited by - idhrendur on December 2, 2003 6:23:47 PM]

Share this post


Link to post
Share on other sites