Thread: Friend operator << with ostream

  1. #1
    Registered User
    Join Date
    Jul 2011
    Posts
    22

    Friend operator << with ostream

    Hi All,

    I'm creating a Fraction class, for study purposes and I'm struggling with a friend operator function in my class.

    this, defined in my header file, within my class.

    Code:
    private:
    int num;
    int den;
    public:
    friend ostream &operator<<(ostream &os, Fraction &fr);
    Then, if i put the following in my .cpp file - it cant cant access the internal methods or data of my class.
    Code:
    ostream &operator<<(ostream &os, Fraction &fr)
    {
    	os << fr.num << "/" << fr.den;
    	return os;
    }
    I thought the whole point of the friend keyword was to define the method as a global function that still has access to the methods and data as a local method has?

    In addition to this, if i put the declaration of my method in the header file, but outside of the class, i get several error msg's when compiling, listed below.

    Code:
    syntax error : missing ';' before '&'
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(22): error C2433: 'ostream' : 'friend' not permitted on data declarations
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(22): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(22): error C2061: syntax error : identifier 'ostream'
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(22): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(22): error C2805: binary 'operator <<' has too few parameters
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(34): error C2143: syntax error : missing ';' before '&'
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(34): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(34): error C2086: 'int ostream' : redefinition
    1>          c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(22) : see declaration of 'ostream'
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(34): error C2065: 'os' : undeclared identifier
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(34): error C2065: 'fr' : undeclared identifier
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(34): error C2275: 'Fraction' : illegal use of this type as an expression
    1>          c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(7) : see declaration of 'Fraction'
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(34): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    1>c:\users\puppy\documents\visual studio 2010\projects\finalfraction\finalfraction.h(34): fatal error C1903: unable to recover from previous error(s); stopping compilation
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    Does anyone have any idea on this. I'd really like to use this method.

    Thanks

    Freem
    Last edited by Freem; 07-18-2011 at 03:46 AM. Reason: typo

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you would show your full code...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Jul 2011
    Posts
    22
    sure. header file.

    Code:
    #include <iostream>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    
    class Fraction
    {
    private:
    	int num;
    	int den;
    public:
    	//constructors
    	Fraction(int n){set(n, 1);}
    	Fraction(){num = 0; den = 1;}
    	Fraction(int n, int d){set(n, d);}
    	Fraction(Fraction const &src); //defined in .cpp
    	//operators
    	Fraction &operator=(const Fraction &src){set(src.num, src.den); return *this;}
    	Fraction operator+(const Fraction &other); //defined in .cpp
    	Fraction operator*(const Fraction &other); //defined in .cpp
    	bool operator==(const Fraction &other); //defined in .cpp
    	friend ostream &operator<<(ostream &os, Fraction &fr);
    	void set(int n, int d){num = n; den = d; normalize();}
    	int get_num(){return num;}
    	int get_den(){return den;}
    	Fraction add(Fraction const &other); //defined in the .cpp
    	Fraction mult(Fraction const &other); //defined in the .cpp
    	
    private:
    	void normalize(); //defined in .cpp
    	int gcf(int a, int b); //defined in .cpp
    	int lcd(int a, int b); //defined in .cpp
    };
    ostream &operator<<(ostream &os, Fraction &fr)
    {
    	os << fr.num << "/" << fr.den;
    	return os;
    }
    and then .cpp file

    Code:
    #include "FinalFraction.h"
    using namespace std;
    int get_number();
    int main()
    {
    	int num;
    	int den;
    	int count = 0;
    	Fraction fract[10];
    	while(true)
    	{
    		cout << "Please enter a value for the num: ";
    		num = get_number();
    		cout << "Please enter a value for the den(hit 0 to end): ";
    		den = get_number();
    		if(den==0)
    			break;
    		fract[count].set(num, den);	
    		count++;
    	}
    	for(int i = 0; i <= count; i++)
    	{
    		cout << "the num entered is " << fract[i].get_num() << " and the den is " << fract[i].get_num() << endl;  
    	}
    	system("pause");
    }
    Fraction::Fraction(Fraction const &src)
    {
    	num = src.num;
    	den = src.den;
    }
    Fraction Fraction::operator+(const Fraction &other)
    {
    	return add(other);
    }
    Fraction Fraction::operator*(const Fraction &other)
    {
    	return mult(other);
    }
    Fraction Fraction::add(Fraction const &other)
    {
    	Fraction fract;
    	int n = gcf(den, other.den);
    	int temp1 = n/den;
    	int temp2 = n/other.den;
    	fract.set(num*temp1 + other.num*temp2, n);
    	return fract;
    }
    Fraction Fraction::mult(Fraction const &other)
    {
    	Fraction fract;
    	fract.set(num*other.num, den*other.den);
    	return fract;
    }
    void Fraction::normalize()
    {
    	if(num==0 || den==0)
    	{
    		num = 0;
    		den = 1;
    	}
    	if (den<0)
    	{
    		num*=-1;
    		den*=-1;
    	}
    	int n = lcd(num, den);
    	num/=n;
    	den/=n;
    }
    int Fraction::gcf(int a, int b)
    {
    	if(b==0)
    		return a;
    	else
    		return gcf(b, a%b);
    }
    int Fraction::lcd(int a, int b)
    {
    	int n = gcf(a, b);
    	return a/n*b;
    }
    bool Fraction::operator==(const Fraction &other)
    {
    	if(num==other.num && den==other.den)
    		return true;
    	else 
    		return false;
    }
    
    int get_number()
    {
    	char s[6];
    	cin.getline(s, 5);
    	if(strlen(s) == 0)
    		return 0;
    	else
    		return atoi(s);
    }
    Thankyou again for looking at it.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    You could easily fix this by not making operator<< a friend at all. operator<< works as well as a non-member non-friend function which calls get_num() and get_den(), so that is one answer you could pursue.

  5. #5
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    I only had a quick look so there might be more problems but this was what I first noticed.
    Quote Originally Posted by Freem View Post
    sure. header file.
    Code:
    ...
    friend std::ostream &operator<<(std::ostream &os, Fraction &fr);
    ...
    std::ostream &operator<<(std::ostream &os, Fraction &fr)
    {
    	os << fr.num << "/" << fr.den;
    	return os;
    }

  6. #6
    Registered User
    Join Date
    Jul 2011
    Posts
    22
    Ofcourse, thanks mike! Ive put using namespace std

  7. #7
    Registered User
    Join Date
    Jul 2011
    Posts
    22
    Ignore my previous comment. But you are totally right, thanks mike.

    I've used the namespace declaration in my .cpp file and not the header file, which is why I'm getting all the compile errors.

    I think... Will have a test when I'm back at my machine.

  8. #8
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Do not put a using namespace declaration in the header file. Prefix the necessary part of the code (just the bits in the header) with std:: as shown in _Mike's post. Keep the declaration in the source file if needed but do not put it in the header.

    A few random links (just to beat the point to death):
    Is it wrong to use C++ 'using' keyword in a header file? - efreedom
    Why is including "using namespace" into a header file a bad idea in C++? - efreedom
    Best practices for use of C++ header files - Stack Overflow
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  9. #9
    Registered User
    Join Date
    Jul 2011
    Posts
    22
    point taken and noted. Thanks guys,

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. friend ostream problem
    By carter88 in forum C++ Programming
    Replies: 5
    Last Post: 12-02-2009, 10:18 AM
  2. ostream operator<< () overload problems
    By jaybny in forum C++ Programming
    Replies: 2
    Last Post: 06-24-2006, 11:00 PM
  3. arithmetic operator friend functions
    By linucksrox in forum C++ Programming
    Replies: 7
    Last Post: 02-06-2006, 11:39 PM
  4. Friend operator saving problem
    By j0hnb in forum C++ Programming
    Replies: 8
    Last Post: 11-10-2004, 10:48 PM
  5. ostream friend
    By MicheleCD in forum C++ Programming
    Replies: 0
    Last Post: 04-27-2003, 08:21 AM

Tags for this Thread