I am trying to overload << for a class complex. The code is:

INTERFACE:

class complex
{
friend ostream& operator<<(ostream& output, const complex& V); 

private:
double REAL;
double IMG; 

public:
complex();
~complex();
};

IMPLEMENTATION of <<:

ostream& operator<<(ostream& output, const complex& V)
{
output<<"("<<V.REAL<< "," << V.IMG<<")";
return output; // for multiple << operators.
}

MS VISUAL C++ 6.0 reports: "error C2248: 'REAL' : cannot access private member declared in class 'complex'."

My understanding is that, << is already defined as a friend
function of the class complex, it should be able to access
the private data REAL and IMG. Why the compiler(I am using Visual
C++ 6.0) says I cant?

Thanks so much.

class complex
{
friend ostream& operator<<(ostream& output, const complex& V);

private:
double REAL;
double IMG;

public:
complex();
~complex();

//Added functions
double GetReal() const {return REAL;}
double GetImg() const {return IMG;}
};

//IMPLEMENTATION of <<:

ostream& operator<<(ostream& output, const complex& V)
{
output<<"("<<V.GetReal()<< "," << V.GetImg()<<")";
return output; // for multiple << operators.
}

I'm not sure that solves your problem. But my best guess is the friend function doesn't have access to the private class members, thus having to use public functions to access them.

1> Please use codeTags to make it easier for everyone to read your code.

2> i dont see a problem here. Is there some more code? Where do you initialize the variables? Post the full code.

3>

But my best guess is the friend function doesn't have access to the private class members

Whats the point of guessing? You either give the right answer or refrain from posting.

Fisrt I'd like to thank you for your code.

I have done exactly the same thing before I post my problem here, and I know it works,
but I wanna know why the friend function cannot
access the private data? Any idea?

Friend function can access private data. Period. Please don't learn wrong things.
For your original problem if you post the code you compiled we should be able to help you understand the real issue.

Presumably you have

#include <iostream>
using namespace std;

or something equivalent in the code before your class declaration. The #include directive is needed (if you don't have it, put it in). The using directive (if you have it) must go, and then replace "ostream" in your class declaration and implementation of the function with "std::ostream".

The reason you need #include <iostream> is to ensure that the compiler sees a definition of std::ostream.

The reason for not having the using directive and using "std::iostream" instead of "ostream" is to remove ambiguity that tends to confuse compilers.

There is also the concern that std::complex (in the standard header <complex>) is a template in the STL - which means more ambiguity if you have a "using namespace std;" in effect.

/*************************************************************************
 
  Contains:
  (i)the interface of the class complex in double precision
  (ii)some complex manipulation functions

  Date: 26 Sept 2007
  Creator: tensor

**************************************************************************/

#ifndef COMPLEX_H
#define COMPLEX_H
#include <iostream>
using namespace std;


/*The class complex interface */
class complex
{
   friend ostream& operator<<(ostream& output, const complex& V);
   private:
   double REAL;
   double IMG;

   public:
	   
   
   complex();
   complex(double R);
   complex(double R, double I);
   complex(complex& V);

   complex operator +(complex& M);
   complex operator +(double M);
   complex operator -(double M);
   complex operator -(complex& M);
   complex operator *(complex& M);
   complex operator *(double M);
   complex operator /(complex& RHS);
   complex operator /(double RHS);
   complex& operator -=(complex& RHS); 
   complex& operator +=(complex& RHS);
   complex& operator =(complex& RHS);
   complex& operator =(double RHS);
   complex& operator *=(complex& RHS);
   complex& operator *=(double RHS);
   complex& operator /=(complex& RHS);
   complex& operator /=(double RHS);
   complex operator -();
   complex& null();
   complex conjugate();
   complex inverse();
   complex normalize();
   
   double norm() const;
   double phase() const; //return the phase of the complex number
   double get_real ()const;
   double get_img ()const;
   
   void set_real(double R);
   void set_img(double I);
   void set(double R, double I); //for a non-null complex number
   void print(); //print in a (real, img) format
   void print1(ostream& output); //print in a real, img format
   void print2(ostream& output); //print in a real + i img formt
   void print(ostream& output); //print in a (real, img) format
   void print1(); //print in a real, img format
   void print2(); //print in a real + i img formt

   bool operator ==(complex& RHS);
   bool operator ==(double RHS);
   
   //ostream& operator<<(const complex& V);
   ~complex();

};


complex expi(double PHASE);

complex operator -(double X, complex& Y);
complex operator *(double X, complex& Y);
complex operator +(double X, complex& Y);
complex exp(complex& C);
complex urc(); //generating unitary real number
complex uic();//generating unitary img number*/
complex pow(const complex& C, double X)

#endif






/*******************************************************

Contains:
(i)The implementation of class complex
(ii)Complex manipulation functions

Date: 30 Oct, 2007
Creator: Tensor

********************************************************/

#include "complex.h"
#include "mconst.h"
#include <cmath>
#include <iostream>
using namespace std;




/************** implementation of class complex ************/
double complex::get_real ()const
{
	return REAL;
}

double complex::get_img ()const
{
	return IMG;
}

void complex::set_real(double R)
{
	REAL = R;
}

void complex::set_img(double I)
{
	IMG = I;
}

void complex::set(double R, double I)
{
	REAL = R;
	IMG = I;
}


bool complex::operator ==(double RHS)
{
	if(REAL==RHS)return true;
	return false;
}

bool complex::operator ==(complex& RHS)
{
	if(REAL == RHS.REAL&&IMG==RHS.IMG)return true;
	return false;
}

complex complex::operator -()
{
	complex TEMP;
	TEMP.REAL =-REAL;
	TEMP.IMG = -IMG;
    return TEMP;
}

complex::complex()
{
	REAL = 0.0;
	IMG =0.0;
}

complex::complex(double R)
{
	REAL = R;
	IMG = 0;
}
complex::complex(double R, double I)
{
	REAL = R;
	IMG = I;
}

complex::complex(complex& V)
{
	this->set_real(V.get_real());
	this->set_img(V.get_img());
}

complex complex::operator +(double M)
{
	complex temp;
	temp.REAL = REAL +M;
	temp.IMG = IMG; 

	return temp;
}

complex complex::operator -(double M)
{
   	complex temp;
	temp.REAL = REAL-M;
	temp.IMG = IMG; 

	return temp;
}

complex& complex::operator /=(complex& RHS)
{
    complex TEMP;
	TEMP.REAL = REAL;
	TEMP.IMG = IMG;

	complex temp2;

	temp2 = TEMP/RHS;
	REAL =temp2.REAL;
	IMG = temp2.IMG;

	return *this;
}

complex& complex::operator /=(double RHS)
{
	REAL /= RHS;
	IMG /=RHS;

	return *this;
}

complex complex::operator /(double RHS)
{
	complex temp;

	temp.REAL = REAL/RHS;
	temp.IMG = IMG/RHS;

	return temp;
}


complex& complex::null()
{
	REAL=0.0;
	IMG =0.0;
	return *this;
}

complex& complex::operator *=(double RHS)
{
   REAL*=RHS;
   IMG*=RHS;

   return *this;
}


complex& complex::operator -=(complex& RHS)
{
	REAL -= RHS.REAL;
	IMG -= RHS.IMG;

	return *this;
}

complex& complex::operator +=(complex& RHS)
{
	REAL += RHS.REAL;
	IMG += RHS.IMG;

	return *this;
}


complex complex::operator /(complex& RHS)
{
  
	return (*this)*RHS.inverse();

}

complex& complex::operator =(complex& RHS)
{
    this->REAL = RHS.REAL;
	this->IMG = RHS.IMG;

	return *this;
}

complex& complex::operator =(double RHS)
{
   REAL = RHS;
   IMG = 0;
   return *this;
}




complex complex::conjugate()
{
	complex CONJ;
	CONJ.REAL = REAL;
	CONJ.IMG = -IMG;
	//complex& theRef =CONJ;
	return CONJ;
}

complex complex::inverse()
{

    return this->conjugate()/((this->norm())*(this->norm()));
}

complex& complex::operator *=(complex& RHS)
{
    double R = REAL;
	double I = IMG;

	REAL = R*RHS.REAL-I*RHS.IMG;
	IMG = I*RHS.REAL+R*RHS.IMG;
	return *this;
}

complex complex::operator +(complex& M)
{
	complex SUM;
	SUM.REAL = REAL+M.REAL;
	SUM.IMG = IMG + M.IMG;
    return SUM;
}


complex complex::operator -(complex& M)
{
    complex SUM;
	SUM.REAL = REAL-M.REAL;
	SUM.IMG = IMG - M.IMG;
	//complex& theRef = SUM;

	return SUM;
}

complex complex::operator *(complex& M)
{
	complex SUM;
	SUM.REAL = REAL*M.REAL-M.IMG*IMG;
	SUM.IMG = IMG*M.REAL + M.IMG*REAL;
	
	//complex& theRef =SUM;
	return SUM;
}

complex complex::operator *(double M)
{

	complex temp;
	temp.REAL=REAL*M;
	temp.IMG=IMG*M;
	return temp;
}

double complex::norm() const
{
	return sqrt(REAL*REAL+IMG*IMG);
}

void complex::print() //print in a (real, img) format
{
  cout<<"("<<this->get_real()<< "," << this->get_img()<<")";
}
   
void complex::print1() //print in a real, img format
{
   cout<<this->get_real()<< "," << this->get_img();
}


void complex::print2() //print in a real + i img formt
{
	cout<<this->get_real()<< "+i" << this->get_img();
}

void complex::print(ostream& output) //print in a real + i img formt
{
	output<<"("<<this->get_real()<< "," << this->get_img()<<")";
}

void complex::print1(ostream& output) //print in a real + i img formt
{
	output<<this->get_real()<< "," << this->get_img();
}

void complex::print2(ostream& output) //print in a real + i img formt
{
	output<<this->get_real()<< "+i" << this->get_img();
}

double complex::phase() const
{
	double ANGLE = atan(IMG/REAL);
	
	if(ANGLE>0)
	{
        if(REAL>0)
		{
			return ANGLE;
		}
		else return ANGLE+PI;
	}
	else
	{
		if(REAL<0)
		{
           return ANGLE + PI;
		}
		else return ANGLE+2.0*PI;
	}
}

complex complex::normalize()
{
    complex TEMP;
	TEMP.REAL = REAL/this->norm();
	TEMP.IMG = IMG/this->norm();
	return TEMP;
}

complex::~complex()
{
	//doing nothing
}


/************************************* end of class complex *********************************
**********************************************************************************************/





/********** Friend Functions*************/

ostream& operator<<(ostream& output, const complex& V) 
{
    output<<"("<<V.REAL<< "," << V.IMG<<")";
    return output;  // for multiple << operators.
}



complex expi(double PHASE)
{
	complex P;

	P.set_real(cos(PHASE));
	P.set_img(sin(PHASE));

	return P;
}


complex operator *(double X, complex& Y)
{
	complex T;
	T.set_real(X*Y.get_real());
	T.set_img(X*Y.get_img());
	return T;
}

complex operator -(double x, complex& Y)
{
	complex T;
	T.set_real(x - Y.get_real());
	T.set_img(x - Y.get_img());;
	return T;
}


complex operator +(double x, complex& Y)
{
	complex T;
	T.set_real(x + Y.get_real());
	T.set_img (Y.get_img());
	return T;
}


complex operator /(double x, complex& Y)
{
    return Y.inverse();
}

complex exp(complex& C)
{
    return exp(C.get_real())*expi(C.get_img());
}

complex urc() //generating unitary real number
{
	complex TEMP(1);
	return TEMP;
}

complex uic()//generating unitary img number
{
	complex TEMP(0,1);
	return TEMP;
}

complex pow(const complex& C, double X)
{
	double T_M = C.norm();
	double T_P = C.phase()*X;
	return complex(T_M*cos(T_P),T_M*sin(T_P));
}

scizj: Look at my previous post. Although I wrote it without having seen your full code, you will find the solution in to your problem within that post.

Hi, everyone:

Thanks for your reply and discussion.

I have compiled my code using Visucal C++ 2008 Expression
edition and it runs very well.

This article has been dead for over six months. Start a new discussion instead.