My friend functions are not getting access to private variables - c++

So I am trying to build a class that can hold information about atomic elements and then do calculations with them. I am getting an error with my overloaded * friend function that says the variable atom_weight is private within the context of the function, but it's a friend so it shouldn't be
// The chemical class
class Chemical{
public:
Chemical();
Chemical(string chemsym);
Chemical(string chemsym, int number, double weight);
void get_element(string chemsym, ifstream& fin);
void clear();
friend Chemical operator +(Chemical& molecule, Chemical& element);
friend Chemical operator *(const Chemical element, int multiplier);
friend Chemical operator >>(istream& ins, Chemical element);
friend Chemical operator <<(ostream& outs, Chemical element);
string get_sym();
int get_num();
double get_weight();
private:
string chemsym;
int atom_num;
double atom_weight;
};
And then here is my function definition for my overloaded * operator.
Chemical operator *(const Chemical& element, int multiplier){
Chemical tempele;
string number;
tempele.atom_weight = element.atom_weight * multiplier;
number = itostr(mulitplier);
tempele.chemsym = element.chemsym + number;
return tempele;
}
Most of my operators are getting similar errors, but my addition one is not even though I can't find any difference. If anyone has any insight on how to solve this problem that would be great.

The function declaration that is at the same time is the function definition does not correspond to the function declaration in the class. Declare the function like
friend Chemical operator *(const Chemical &element, int multiplier);
^^

Related

Member is inaccessible when overloaded operator is friended

The code doesn't link when I try to compile, the error is "undefined reference to operator*" and I think this may be the problem.
This is my .h file:
namespace space{
class Number{
.
.
public:
friend Number operator*(double scaler, const Number& one);
private:
int val;
std::string unit;
.
}
This is the .cpp file:
using namespace space;
Number operator*(double scaler, const Number& one){
Number temp((one.val * scaler), one.unit);
return temp;
}
But I'm getting the error (it's right on the one.val):
member "space::Number::val" (declared at line 47 of ".../Number.hpp") is inaccessibleC/C++(265)
The friend declaration is a declaration of a function:
namespace space{
class Number{
friend Number operator*(double scaler, const Number& one);
// ...
};
As this is inside a namespace, the function that is declared is space::operator*. Then you define ::operator* in the global namespace. Those are two different functions. You made one operator a friend of the class, but define a different one.
The operator that you made a friend must be defined inside the namespace (or you declare the one in global scope as friend):
namespace space {
Number operator*(double scaler, const Number& one){
Number temp((one.val * scaler), one.unit);
return temp;
}
}

Problem with overloading input operator in c++

I started to learn C++ recently and i ran into this trouble with using overloaded input operator >>.
I am writing a class to describe a Complex number.
My problem is: If i put my main() in the Complex.cpp, my program run normally. But if i create a new file main.cpp and put my main() there i ran into error.
error: invalid operands to binary expression ('std::istream' (aka 'basic_istream') and 'Complex')
candidate function not viable: no known conversion from 'std::istream' (aka 'basic_istream') to 'std::istream *' (aka 'basic_istream *') for 1st argument; take the address of the argument with &
(There are a lots more error bellow but they point to istream so i don't think that is the problem)
This is my header file:
#include <iostream>
using namespace std;
#ifndef HEADER_H
#define HEADER_H
#endif // HEADER_H
class Complex
{
public:
double _real;
double _imag;
public:
Complex(double, double);
double getReal() const;
double getImag() const;
void setReal(double);
public:
Complex operator=(const Complex&);
Complex * operator+(const Complex&);
Complex * operator+(const double&);
friend Complex * operator+(const double&, const Complex&);
Complex * operator++();
Complex * operator++(int);
Complex * operator--();
Complex * operator--(int);
operator double() const;
friend ostream &operator<<(ostream*, const Complex&);
friend istream &operator>>(istream*, Complex&);
};
And i created Complex.cpp to identify the function:
#include "Complex.h"
using namespace std;
Complex::Complex(double a, double b)
{
this->_real = a;
this->_imag = b;
}
double Complex::getReal() const{...}
void Complex::setReal(double x){...}
double Complex::getImag() const{...}
Complex Complex::operator=(const Complex& other){...}
Complex * Complex::operator+(const Complex& other){...}
Complex * Complex::operator+(const double &other){...}
Complex * operator+(const double &first, const Complex &second){...}
Complex * Complex::operator++(){...}
Complex * Complex::operator++(int){...}
Complex * Complex::operator--(){...}
Complex * Complex::operator--(int){...}
Complex::operator double() const{...}
ostream &operator<<(ostream &output, const Complex &comp)
{
output << comp._real << " + " << comp._imag << "i";
return output;
}
istream &operator>>(istream &input, Complex &comp)
{
input >> comp._real >> comp._imag;
return input;
}
This is my main:
#include "Complex.h"
int main()
{
Complex com4(0,0);
cout << "Input Complex: ";
cin >> com4;
cout << com4 <<endl;
}
You declared io operators with pointers (which is wrong)
friend ostream &operator<<(ostream*, const Complex&);
friend istream &operator>>(istream*, Complex&);
but implemented it correctly with references.
friend ostream &operator<<(ostream&, const Complex&) {...}
friend istream &operator>>(istream&, Complex&) {...}
When you have your main() in Complex.cpp, the compiler can see those correct implementations (that are not defined in any header).
If you have your main() somewhere else, the compiler can only see the declarations in the header, which have the wrong signature.
Solution will be to fix the declarations of operator<< and operator>> in the header, so that they match the implementation.
As a note and as already mentioned in the comments: Your other operator-overloads should return Complex & or Complex not Complex *. Take a look at std::complex or this page, detailing operator overloading to see what the canoncial implementations look like.

friend function has no access to private class members

I am still new to C++ and as part of an assignment I have written a class that needs an overload of the stream extraction operator '>>' for file stream extraction in order to make things a bit easier, so says the instructions. I have declared and defined 2 overloads for both operators, one oveload for iostream objects and one overload for fstream object. Now, everything is fine until i get to the definition of '>>' for file stream objects, apparently that function has no access to the private (or protected) member of the class of which it is a friend of.
Here is my code, i thank you all in advance:
stock.h
#ifndef STOCK_H
#define STOCK_H
#include<iostream>
#include<fstream>
class Stock_Type
{
friend std::ostream& operator<<(std::ostream&, const Stock_Type&);
friend std::istream& operator>>(std::istream&, Stock_Type&);
friend std::ofstream& operator<<(std::ofstream&, const Stock_Type&);
friend std::ifstream& operator>>(std::ofstream&, Stock_Type&);
public:
//constructor overloads-----------------------------------------------------------------------------------------------------
Stock_Type(){};
Stock_Type(std::string sym, double a, double b, double c, double d, double e, int f, double g) :
stock_symbol(sym), opening_price(a), closing_price(b), high_price(c), low_price(d), prev_close(e), volume(f), percent_gain(g) {}
//default destructor--------------------------------------------------------------------------------------------------------
~Stock_Type(){};
//accessor functions--------------------------------------------------------------------------------------------------------
void set_Symbol(std::string x){stock_symbol = x;}
void set_Closing_Price(double x){closing_price = x;}
void set_High_Price(double x){high_price = x;}
void set_Low_Price(double x){low_price = x;}
void set_Prev_Close(double x){prev_close = x;}
void set_Volume(int x){volume = x;}
std::string get_Stock_Smybol(){return stock_symbol;}
double get_Opening_Price(){return opening_price;}
double get_Closing_Price(){return closing_price;}
double get_High_Price(){return high_price;}
double get_Low_Price(){return low_price;}
double get_Prev_Close(){return prev_close;}
int get_Volume(){return volume;}
double get_Percent_Gain_Loss(){return get_Closing_Price() - get_Opening_Price();}
//operations on Stock_Type-------------------------------------------------------------------------------------------------------
//operator functions--------------------------------------------------------------------------------------------------------------
bool operator==(const Stock_Type&)const;
bool operator!=(const Stock_Type&)const;
bool operator<(const Stock_Type&) const;
bool operator<=(const Stock_Type&)const;
bool operator>(const Stock_Type&)const;
bool operator>=(const Stock_Type&)const;
friend std::ostream& operator<<(std::ostream&, const Stock_Type&);
friend std::istream& operator>>(std::istream&, Stock_Type&);
const Stock_Type& operator=(const Stock_Type &right_operand);
Stock_Type& operator[](int elem);
const Stock_Type& operator[](int elem) const;
private:
std::string stock_symbol;//record data1
double opening_price, closing_price, high_price, low_price, prev_close;//record data2
int volume;//record data3
double percent_gain;//record data 4
Stock_Type *stock_pointer;
int array_size;
};
#endif
stock.cpp, i will only include the function for which an error is generated
std::ifstream& operator>>(std::ifstream& if_obj, Stock_Type& stock_obj)
{
if_obj >> stock_obj.stock_symbol
>> stock_obj.opening_price
>> stock_obj.closing_price
>> stock_obj.high_price
>> stock_obj.low_price
>> stock_obj.prev_close
>> stock_obj.volume
>> stock_obj.percent_gain;
return if_obj;
}
the error is that for all the attributes that are listed are "inaccessible"
I'd like to finish this assignment as I'd like to move on to another one that is due on exception handling.
Thank you all in advance, once again.
i apologize, I believe that the signatures in the definition and implementation were different, as pointed out by a previous comment, i declared a friend function twice and there i saw my error, i did not change the code after copy/pasting it. For all future readers: MAKE SURE DECALRATION SIGNATURES MATCH IMPLEMENTATION SIGNATURES!
There is a
friend std::ifstream& operator>>(std::ofstream&, Stock_Type&);
but you have access problems in
std::ifstream& operator>>(std::ifstream& if_obj, Stock_Type& stock_obj)
Adding another friend should help.
friend std::ifstream& operator>>(std::ifstream& if_obj, Stock_Type& stock_obj);
Actually, you might prefer to edit the existing friend, it very much looks like a typo or other kind of trivial error.

Operator Overloading in C++ (small error)

I have a small error with operator overloading that's been bugging me.
I've got a class:
class Fraction{
private:
//Variables
int numerator;
int denominator;
//Constructor
public:
//Methods
Fraction();
Fraction(int, int);
};
I also have this operator overloading function:
Fraction& operator+=(const Fraction& f);
It seems like it would build fine to me, but the compiler is giving me this error message:
In file included from Fraction.cpp:3:
./Fraction.h:31:11: error: overloaded 'operator+=' must be a binary operator
(has 1 parameter)
Fraction& operator+=(const Fraction& f);
^
1 error generated.
Every single example of += I've seen so far is identical to what I'm doing as far, from what I can tell. If someone could point out my stupidity, that would be great!
Either declare the operator as a member function of the class or if it is a non-class function then it shall have two parameters
For example
1 member function
class Fraction
{
private:
//Variables
int numerator;
int denominator;
//Constructor
public:
//Methods
Fraction();
Fraction(int, int);
Fraction& operator +=( const Fraction &rhs );
};
2. non-member function
class Fraction
{
private:
//Variables
int numerator;
int denominator;
//Constructor
public:
//Methods
Fraction();
Fraction(int, int);
friend Fraction& operator +=( Fraction &lhs, const Fraction &rhs );
};
Fraction& operator +=( Fraction &lhs, const Fraction &rhs ) { /* some code */ }
Take into account that then the operator is a non-class function you may not use this
Also the non-class operator should be a friend function of the class if there is no public access to corresponding data members through getters and setters.
You should put
Fraction& operator+=(const Fraction& f);
declaration inside class if it has to be binary operation. Alternatively you can declare this operator in global namespace taking two instances of Fraction, but make it friend of this class (as it needs access to private data) by declaring friendship in Fraction through:
friend Fraction& operator+=( Fraction& l, const Fraction& r);
You are defining a free function, it should have 2 parameters (binary operator).
Declare it inside the Fraction class instead.
If you overload the operator as a non-member function you need to write it like this
Fraction& operator+=(const Fraction& lhs, const Fraction& rhs);
This errors occurs when your overloaded operator is outside your class as global.
You should try give declaration of this operator into your class as:
Fraction& operator+=(const Fraction& f);
You can leave as you did but then you must change operator to this:
Fraction& operator+=(const Fraction& f, const Fraction& g);
Here you can find some more information in my post

C++ operator overriding w/ arguments from 2 classes

I'm new to object oriented programming and I'm wondering if it's possibile to create an operator for one class which will use arguments from this class and another one, declared by me.
The problem I have to solve is a linear translation on a given point. So I created classes Point and LinearTranslation and basically what I want to do is to create an operator
Point operator* (Point p, LinearTranslation l)
which would take Point p, do the translation l and then return Point. I'm getting weird errors though: Point operator*(int)’ must have an argument of class or enumerated type or that LinearTranslation has not been declared.
Is it even possibile?
ok i'm posting only a bit because it's kind of assignment so I have class Point.h
sorry for the mess but I'm trying a bit everything and it's not working for me.
#include "LinearTranslation.h"
class Point {
public:
int N;
double* coordinates;
public:
Point(int, double*);
virtual ~Point();
double operator[](int a);
//friend Point operator*(LinearTranslation l);
friend Point translation(LinearTranslation l);
};
LinearTranslation.h
#include "Point.h"
class LinearTranslation {
private:
int N;
double* vector;
double** matrix;
public:
//friend class Point;
LTrans(int,double*,double**);
LTrans(int);
virtual ~LTrans();
void write_vector();
void write_matrix();
LinearTranslation operator+(const LinearTranslation&);
friend Point& translation(LTrans l, Point p);
//friend Point& operator* (Point p, LTrans l);
};
in your class declaration:
//friend Point operator*(LinearTranslation l);
a friend operator overloading function takes two parameters for the function, you only declare one in your code. The most common example of a friend function is using the overloaded operator << like so:
friend ostream& operator<<(ostream& output, const Point& p);
note that this function takes the output as its first parameter, and the point as its second parameter.
Your fix would be to add in your operand to the function
friend Point operator*(LinearTranslation l, const int& MULT);