Can't access private members of a class despite friend class - c++

I am doing a homework assignment on overloading operators. This is my code:
#include<iostream>
#include<cmath>
using namespace std;
class ComplexNumber{
double real;
double imaginary;
public:
friend class Equation;
};
class Equation{
ComplexNumber *broevi;
char *znaci;
int n;
public:
Equation(){
broevi=new ComplexNumber[0];
znaci=new char[0];
n=0;
}
friend istream &operator >>(istream &in, Equation &e){
int k=1;
while(k){
char *tmp; ComplexNumber *b;
tmp=new char[e.n+1];
for(int i=0; i<e.n; i++)
tmp[i]=e.znaci[i];
b=new ComplexNumber[e.n+1];
for(int i=0; i<e.n; i++)
b[i]=e.broevi[i];
in>>e.broevi[e.n].real>>e.broevi[e.n].imaginary;
in>>tmp[e.n];
if(tmp[e.n]=='=')
break;
delete []e.znaci;
e.znaci=tmp;
delete[]e.broevi;
e.broevi=b;
++e.n;
}
return in;
}
friend class ComplexNumber;
};
This is only a part of my code.
While compiling I get these two following errors:
error: 'double ComplexNumber::imaginary' is private
error: 'double ComplexNumber::real' is private
On this line:
in>>e.broevi[e.n].real>>e.broevi[e.n].imaginary;
Can you please point out where my mistake is?

Your operator>> is a friend of Equation, so it can access private fields of Equation. But, it is not a member of Equation, and it is not a friend of ComplexNumber, so it can't access private fields of ComplexNumber.
The simplest solution is to add a friend operator>> to ComplexNumber, and then use that in Equation's operator>>:
class ComplexNumber {
double real;
double imaginary;
public:
friend istream& operator >>(istream &in, ComplexNumber &cn) {
in >> cn.real >> cn.imaginary;
return in;
}
};
class Equation {
...
public:
...
friend istream& operator >>(istream &in, Equation &e) {
...
//in >> e.broevi[e.n].real >> e.broevi[e.n].imaginary;
in >> e.broevi[e.n];
...
}
};
However, if that is not allowed for your assignment, then you can instead move your stream logic to a member method of Equation for its operator>> to call, and then that method will have access to the private fields of ComplexNumber:
class ComplexNumber {
double real;
double imaginary;
public:
friend class Equation;
};
class Equation {
...
void read(istream &in) {
// your logic here...
}
public:
...
friend istream& operator >>(istream &in, Equation &e){
e.read(in);
return in;
}
};

Related

How to call a operator overloaded function from other functions / methods in c++?

I have another class object in my class. Ex:
ParkingMeter.h
class ParkingMeter
{
private:
ParkedCar pCar;
int minutesPurchased = 0;
public:
friend std::istream& operator >> (std::istream, ParkingMeter&);
};
ParkedCar.h
class ParkedCar
{
private:
std::string maker;
std::string model;
std::string color;
int licenseNumber = 0;
int minutesParked = 0;
public:
friend std::istream& operator >> (std::istream&, ParkedCar&);
friend std::ostream& operator << (std::ostream&, ParkedCar&);
};
So, when I enter the data for ParkingMeter object with it's respective operator overloaded, I want to call the overloaded function for the ParkedCar object aswell.
This is what I've got. The operator overloaded function for the ParkingMeter:
std::istream& operator>>(std::istream is, ParkingMeter& obj)
{
cout << "How many minutes to buy? ";
is >> obj.minutesPurchased;
cout << "Enter the information about your car:\n";
is >> obj.pCar;
return is;
}
But in my main file, the following code don't word:
ParkingMeter temp;
std::cin >> temp;
Thank you.
Solution
Thanks to #L. F. for pointing my silly mistake. :D
I've forgotten to use the & after std::istream in the arguments for the function:
friend std::istream& operator >> (std::istream, ParkingMeter&);
Now its works fine:
friend std::istream& operator >> (std::istream&, ParkingMeter&);

how to use std in code without including "using namespace std"?

In this code of operator Overloading, i don't want to write "using namespace std" instead i want to include "std::" wherever required.
After adding "std::" after cout and cin, i am still getting Errors where else to include "std::".
#include<iostream>
//using namespace std;
class Complex
{
private:
int real, imag;
public:
Complex(int r = 0, int i = 0) : real(r), imag(i) {}
friend ostream & operator << (ostream &, const Complex &);
friend istream & operator >> (istream &, Complex &);
};
ostream & operator << (ostream &out, Complex &obj)
{
out<<obj.real<<" "<<obj.imag;
return out;
}
istream & operator >> (istream &in, const Complex &obj)
{
in>>obj.real>>obj.imag;
return in;
}
int main()
{
Complex obj;
std::cin>>obj;
std::cout<<obj;
return 0;
}
It should take input two numbers using istream operator and output two numbers using ostream operator.
add std:: to ostream and istream
They come from the headers <istream> and <ostream> and are defined in <iosfwd>
#include<iostream>
//using namespace std;
class Complex
{
private:
int real, imag;
public:
Complex(int r = 0, int i = 0) : real(r), imag(i) {}
friend std::ostream& operator<<(std::ostream& out, const Complex& obj);
friend std::istream& operator>>(std::istream& in, Complex& obj);
};
std::ostream& operator<<(std::ostream &out, const Complex &obj)
{
out << obj.real << " " << obj.imag;
return out;
}
std::istream& operator>>(std::istream &in, Complex &obj)
{
in >> obj.real >> obj.imag;
return in;
}
int main()
{
Complex obj;
std::cin >> obj;
std::cout << obj;
return 0;
}
(not related to the std:: problem)
You can also access your private variables outside the class without the friend declaration by using get/set member functions. Thanks to #aschepler for pointing out my mistake regarding the accessibility.
#include<iostream>
class Complex
{
private:
int real, imag;
public:
int get_real() const {
return real;
}
void set_real(int real) {
this->real = real;
}
int get_imag() const {
return imag;
}
void set_imag(int imag) {
this->imag = imag;
}
Complex(int r = 0, int i = 0) : real(r), imag(i) {}
};
std::ostream& operator<<(std::ostream &out, const Complex &obj)
{
out << obj.get_real() << " " << obj.get_real();
return out;
}
std::istream& operator>>(std::istream &in, Complex &obj)
{
int real, imag;
in >> real >> imag;
obj.set_real(real);
obj.set_imag(imag);
return in;
}
int main()
{
Complex obj;
std::cin >> obj;
std::cout << obj;
return 0;
}
Your favourite standard library reference tells you what namespace things are in. In a tiny program like this, you can simply look up each one in turn.
Hint: they're all in std.
So that includes std::ostream and std::istream.
This is just a namespace pollution problem. The importance of it may vary between usages.
When you are just prototyping, using namespace std; is fine, as is including useless headers just in case you need something from one. When you want a super safe code that will be extensively reviewed, you want to prevent name collision and namespace pollutino, so you include in the current namespace only what is required, and you give explicit namepaces for idendifiers that are only seldom used.
The following is more of my own opinion (or more exactly the way I am used to work):
when a symbol is seldom used, I give it its explicit namespace (eg: std::cout << i;)
when a symbol is heavily used in a compilation unit, I import specifically that symbol (eg: using std::cout; ... cout << i; ... cout << j; ...)

Operation with 2 friends constructor

I created two classes and a constructor in each. Type followed a new class and constructors friends functions of the classes before.
#include <iostream>
using namespace std;
class clsAtmosfericConditions;
class clsDensity{
float density;
public:
clsDensity(){}
clsDensity(float densidad){
density = densidad;
}
friend istream& operator >>(istream &i, clsDensity &e);
friend ostream& operator <<(ostream &o, const clsDensity &s);
};
istream& operator >>(istream &i, clsDensity &e){
char sign;
i >> e.density >> sign >> sign >> sign >> sign >> sign >> sign;
return i;
}
ostream& operator <<(ostream &o, const clsDensity &s){
o << s.density << " Kg/m^3";
return o;
}
class clsDynamicViscocity{
double dynamicViscocity;
public:
clsDynamicViscocity(){}
clsDynamicViscocity(double viscocidadDinamica){
dynamicViscocity = viscocidadDinamica;
}
friend istream& operator >>(istream &i, clsDynamicViscocity &e);
friend ostream& operator <<(ostream &o, const clsDynamicViscocity &s);
};
istream& operator >>(istream &i, clsDynamicViscocity &e){
char sign;
i >> e.dynamicViscocity >> sign >> sign >> sign >> sign >> sign;
return i;
}
ostream& operator <<(ostream &o, const clsDynamicViscocity &s){
o << s.dynamicViscocity << " N/m^2";
return o;
}
class clsAtmosfericConditions{
friend clsDynamicViscocity::clsDynamicViscocity(double viscocidadDinamica);
friend clsDensity::clsDensity(float densidad);
public:
float kinematicViscocity();
};
float kinematicViscocity(){
float kinematicViscocity;
kinematicViscocity = dynamicViscocity/density; //Here is where IDE gives me the error
return kinematicViscocity;
}
The IDE displays an error in the function: error: 'dynamicViscocity' undeclares (first use this function)
I checked on some websites and I see no need to pass values ​​by reference builder when you do the operation.
Couple of problems here.
dynamicViscocity is a member of class clsDynamicViscocity. kinematicViscocity is not a member of any class, but I suspect is is intended to be a member of clsAtmosfericConditions. Regardless, kinematicViscocity is not a member of clsDynamicViscocity, so in order to operate on dynamicViscocity, it needs an object of type clsDynamicViscocity to provide dynamicViscocity.
Second, the visibility (public, private, protected) of dynamicViscocity is not specified, so C++ defaults to the most restrictive, private. A private member cannot be seen except by the object and those the object has defined as friends.
So kinematicViscocity has no dynamicViscocity and even if it did, it cannot see dynamicViscocity.
Suggested solution
Change the definition of kinematicViscocity to
float clsAtmosfericConditions::kinematicViscocity(const clsDynamicViscocity & vis,
const clsDensity & den)
{
float kinematicViscocity;
kinematicViscocity = vis.getDynamicViscocity() / den.getDensity();
return kinematicViscocity;
}
to provide a clsDynamicViscocity to kinematicViscocity and add a getter function
double getDynamicViscocity() const
{
return dynamicViscocity;
}
to clsDynamicViscocity.
The same needs to be done to access density from clsDensity.
EDIT
Waaaait a second...
Finally figured out what you are trying to do here:
friend clsDynamicViscocity::clsDynamicViscocity(double viscocidadDinamica);
friend clsDensity::clsDensity(float densidad);
A class declares who they will allow to see and use their hidden internals. A class cannot declare who's hidden internals they can see. Think of it this way, Bob can be friends with Alice and show her his secrets, but Bob cannot force Alice to be his friend and show him her secrets. Alice has to make that decision herself.
What the above means is the two methods can can violate encapsulation and see the hidden internals of clsAtmosfericConditions. clsAtmosfericConditions cannot however see the internals of clsDynamicViscocity or clsDensity.
clsDynamicViscocity and clsDensity have to friend class clsAtmosfericConditions to allow clsAtmosfericConditions to see into them, not the other way around.
So
clsDensity()
{
friend class clsAtmosfericConditions;
...
}
and
clsDynamicViscocity()
{
friend class clsAtmosfericConditions;
...
}
Now change kinematicViscocity to look like this:
float clsAtmosfericConditions::kinematicViscocity(const clsDynamicViscocity & vis,
const clsDensity & den)
{
float kinematicViscocity;
kinematicViscocity = vis.dynamicViscocity / den.density;
return kinematicViscocity;
}
and you are golden.
The original solution with the getters is a better solution as it requires no friends whatsoever and is much less tightly coupled. The guts of clsDynamicViscocity and clsDensity can be radically changed without breaking clsAtmosfericConditions so long as the getter function prototypes remain the same and clsAtmosfericConditions is granted no more access to clsDynamicViscocity and clsDensity than is required to get data.

cannot access protected member declared in class from a friend function in derived class

i've a base class as follows:
//base class- arrayListType.h
class arrayListType
{
public:
//some function members;
protected:
elemType *list;
int length;
int maxSize;
};
and then a derived class:
//derived class- polynomialType.h
#include "arrayListType.h"
class polynomialType: public arrayListType<double>
{
friend ostream& operator<<(ostream& ,const polynomialType&);
friend istream& operator>>(istream& ,polynomialType&);
public:
polynomialType operator+(const polynomialType&);
polynomialType operator-(const polynomialType&);
//polynomialType operator*(const polynomialType&);
double operator() (double x);
polynomialType(int size = 100);
int min(int x,int y) const;
int max(int x,int y) const;
};
But after compiling the code, i got error as;
error C2248: 'arrayListType<elemType>::length' : cannot access protected member declared in class 'arrayListType<elemType>'
i've searched for solutions, but can't find ,please help.
definition of operator>> is given for refference;
istream& operator>>(istream is,polynomialType& p)
{
cout << "the degree of this polynomial is" << p.length-1 << endl;
for (int i = 0; i < p.length; i++)
{
cout << "enter coefficient of x^" << i <<": ";
is >> p.list[i];
}
return is;
}
the error shows only for friend functions only, why is it so??
friend istream& operator>>(istream& ,polynomialType&);
verses
istream& operator>>(istream is,polynomialType& p)
Your stream function forgot the reference operator & and therefore has a different function signature. Not only that but it can also lead to subtle bugs such as copying the stream object (which may or may not have additional side effects) instead of re-using it.

Private members of class - within this context

I get weird notification that I'm using private members of class - which is entirely valid, but I though that I'm allowed to do so, since I did say that the method I'm using is a friendly one.
Take a look at this:
#include <iostream>
using namespace std;
class complex {
private:
double Re, Im;
public:
complex(): Re(0.0), Im(0.0){}
complex(double Re, double Im): Re(Re), Im(Im){}
double getRe() const { return Re; }
double getIm() const { return Im; }
friend complex operator+(const complex&, const complex&);
friend ostream& operator<<(ostream&, const complex&);
friend istream& operator>>(istream &, const complex &); // FRIENDLY FUNCTION
};
complex operator+(const complex& a, const complex& b) {
double r, i;
r = a.getRe()+ b.getRe();
i = a.getIm() + b.getIm();
return complex(r, i);
}
ostream& operator<<(ostream& out, const complex &a) {
out << "(" << a.getRe() << ", " << a.getIm() << ")" << endl;
return out;
}
istream &operator>>(istream &in, complex &c)
{
cout<<"enter real part:\n";
in>>c.Re; // ** WITHIN THIS CONTEXT ERROR **
cout<<"enter imag part: \n";
in>>c.Im; // ** WITHIN THIS CONTEXT ERROR **
return in;
}
int main(void) {
complex a, b,c;
cin >> a;
cin >> b;
c = a+b;
cout << c;
}
Should I declare some sort of setFunction within the class in order to get the values which are private ?
istream& operator>>(istream &, const complex &);
is not the same as
istream &operator>>(istream &in, complex &c);
Spot the difference left as exercise to the reader.