Member is inaccessible when overloaded operator is friended - c++

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;
}
}

Related

My friend functions are not getting access to private variables

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);
^^

Friend operator in different namespace

Currently the following code is not working:
namespace inner
{
struct Test
{
Test() : n(0) { }
friend int ::operator+(const Test& a, const Test& b);
private:
int n;
};
}
int operator+(const inner::Test& a, const inner::Test& b)
{
return a.n + b.n;
}
and the error I get is
error: 'int operator+(const inner::Test&, const inner::Test&)' should have been declared inside '::'
friend int ::operator+(const Test& a, const Test& b);
^
I thought qualifing the namespace would fix the problem but it doesn't. What's a workaround?
A friend declaration can only introduce a name into the immediately surrounding namespace.
If you want to befriend a function in any other namespace, then you'll need to declare that function, in its namespace, before the friend declaration. As the error message says.
In this case, you probably want the operator to be in inner rather than the global namespace. Argument-dependent lookup will still find it in an expression like test_a + test_b, even if it's not otherwise in scope.
You have to declare the operator before its usage in the structure.

What does 'must have an argument of class or enumerated type' actually mean

I have a header file and a .cpp file. I an needing to write functions for my .h file but i get an error before i can fully complete a skeleton .cpp file.
Money.h
#ifndef MONEY_H
#define MONEY_H
#include <iostream>
#include <iomanip>
using namespace std;
class Money
{
public:
Money(int dollars, int cents);
Money operator+(const Money& b) const;
Money operator-(const Money& b) const;
Money operator*(double m) const;
Money operator/(double d) const;
void print() const;
private:
int dollars;
int cents;
};
#endif
Money.cpp
#include "Money.h"
Money::Money(int dollars, int cents){
}
Money operator+(const Money& b) {
}
Money operator-(const Money& b) {
}
Money operator*(double m) {
}
Money operator/(double d) {
}
void print(){
}
The errors are with the multiply and divide operators:
Money.cpp:12:25: error: 'Money operator*(double)' must have an
argument of class or enumerated type
Money.cpp:15:25: error: 'Money operator/(double)' must have an
argument of class or enumerated type
You're not using the scope resolution operator to tell the compiler that you are defining a member function. It is instead interpreted as a global operator overload, which takes two arguments, one of which must be of class or enumerated type. This basically means that one of your arguments must either be a user-defined type (type that is not a primitive type) or an enumerated type which is defined through an enum.
In your original code Money is just the return type; it doesn't tell the compiler that you are defining member function from that class.
Here is a fix for one of your lines:
Money Money::operator+(const Money& b) /*
^^^^^^^ */
{
// ...
}
Moreover, your prototypes and definitions must also match in cv-qualification. Your definitions were missing the const qualifier...
Money Money::operator+(const Money& b) const /*
^^^^^ */
{
// ...
}
Update:
I also found that your definition for Money::operator* and Money::operator/ do not match their prototypes. The prototypes for both take a double while the definitions take Money const&. You will need to change one to match the other.
// inside Money class
Money operator*(Money const&) const;
Money operator/(Money const&) const;

Writing the implementation for an operator method

So I have a LongInt class that will have new definition for the + and * operators. The initialization in the header file looks like:
friend LongInt operator+(const LongInt& x, const LongInt& y);
friend LongInt operator*(const LongInt& x, const LongInt& y);
however in my implementation file, where I'm defining the methods found in the header, VS doesn't recognize the operator+ function or the operator* function as being listed in the header. I'm using the code:
friend LongInt LongInt::operator+(const LongInt& x, const LongInt& y)
{
}
and
friend LongInt LongInt::operator*(const LongInt& x, const LongInt& y)
{
}
Any ideas as to why this code wont work when I'm trying to define the operators?
The friend keyword is only used when declaring or defining the operator inside of a class; when declaring the operator as a friend inside of the class and defining it elsewhere, friend is only used on the declaration, not the definition. Also, functions declared as friend inside a class are in fact free functions in namespace scope, not class members. So, your definitions should look more like:
LongInt operator +(LongInt const& x, LongInt const& y) { /*...*/ }
LongInt operator *(LongInt const& x, LongInt const& y) { /*...*/ }
For further reading material, read over the following page: C++ FAQ: Friends
You're overriding an operator ... you "call" it using the operator:
LongInt foo;
LongInt bar;
LongInt foobar = foo + bar;

C++ friend operator+ overloading

I'm confused about friend operator overloading. It has no problem if I write the friend operator overloading function within the header file, but it gives me the following errors once I moved the function to class file. I googled some samples and they all written the function in the header file. What did I do wrong? Thanks.
...: error: expected ‘,’ or ‘...’ before ‘&’ token
...: error: ISO C++ forbids declaration of ‘statisticain’ with no type
...: error: ‘main_savitch_2C::statistician operator+(int)’ must have an argument of class or enumerated type
// a.h
class A
{
public:
friend A operator + (const A &a1, const A &a2);
};
// a.cpp
#include "a.h"
A operator + (const A &a1, const A &a2)
{
//
}
From the error message you're getting:
ISO C++ forbids declaration of ‘statisticain’ with no type
I think that you misspelled "statistician" by reversing the last two letters (note that you have "statisticain" instead of "statistician.")
This should have nothing to do with whether operator+ is implemented in the header or the .cpp file.
I agree with the previous answer. Also, if I may ask, why make the function a friend when both arguments and the return type are of the same class? why not make it a member so the first argument is passed implicitly by the this operator?
Move the two param version out of the class declaration. Or just use one param and the this pointer.
Here's an abbreviated real world example.
//complexnumber.h
class ComplexNumber
{
float _r;
float _i;
friend ComplexNumber operator+(const ComplexNumber&, const ComplexNumber&);
public:
ComplexNumber(float real, float img):_r(real),_i(img) {}
ComplexNumber& operator + (const ComplexNumber &other);
};
ComplexNumber operator+(const ComplexNumber &c1, const ComplexNumber& c2);
//complexnumber.h
ComplexNumber operator+(const ComplexNumber &c1, const ComplexNumber& c2)
{
return ComplexNumber(c1._r+c2._r, c1._i+c2._i);
}
// static
ComplexNumber& ComplexNumber::operator + (const ComplexNumber &other)
{
this->_r = this->_r + other._r;
this->_i = this->_i + other._i;
return *this;
}