Fixing "this" error in c++ - c++

I'm still new to c++ and I was wondering why I keep getting the error "invalid use of 'this' in non-member function" for every instance of "this" in my cpp file.
cpp file (just method)
ostream & operator<< (ostream & outS, Complex & rhs) {
cout << this->real;
if (this->imag < 0) {
cout << "-";
if (this->imag != -1)
cout << (-this->imag);
cout << "i";
} else if (this->imag >0){
cout << "+";
if (this->imag != 1)
cout << this->imag;
cout << "i";
return outS;
}
header file (part of)
public:
friend ostream & operator<< (ostream&, Complex&);
I also seem to be getting the error "'Complx' does not name a type
Complx::Complex (const Complex& object)"
^
cpp file
Complx::Complex (const Complex& object) {
real = object.real;
imag = object.imag;
}
header file
public:
Complex (const Complex&);
Any help would be much appreciated, and I can post the rest of my code if needed (I figured just posting parts of it would be easier to read).

this refers to your current object -- the object that the method is a part of. When your method stands alone, it's not part of an object so this has no meaning. It appears that instead of this-> you intend to refer to rhs..

In your operator<<, it is NOT a member of your class. Thus, it does not have this pointer, which is only for class non-static members.
class Complex
{
double imag, real;
public:
Complex(const _real=0.0, const _imag=0.0);
Complex(const Complex&);
// friend functions are not member of the class
friend ostream& operator<< (ostream&, Complex&);
// this is a member of the class
Complex operator+(Complex& another)
{
// I am a member so I have 'this' pointer
Complex result;
result.real = this->real + another.real;
result.imag = this->imag + another.imag;
return result;
}
};
ostream& operator<<(ostream& stream, Complex& rhs)
{
// I do not have 'this' pointer, because I am not a member of a class
// I have to access the values via the object, i.e. rhs
stream << rhs.real << "+" << rhs.imag << 'i';
return stream;
}
Yet my question is, why do you want to use 'friend operator<<'? IMHO it should not be a friend of the class, instead, the class should provide functions like double image() const { return this->imag; }, and the non-friend operator<< can access the values via these functions.

Related

Call to deleted constructor of std::__1::ostream error on operator<< overload

I am trying to get a function to be recognized as a friend but I can not figure out what I am doing wrong. I tried changing things to references and moving things in and out of the namespace and header cpp. There is nothing that I notice as the culprit for why this does not work.
The error I am getting is
error: call to deleted constructor of 'std::__1::ostream' (aka 'basic_ostream<char>')
return output;
^~~~~~
I'm thinking it might be a reference issue, or maybe something I forgot to import when I started. But I can't think of anything.
namespace N
{
class Complex
{
public:
// Contructors
Complex(double n, double i)
{
this->number = n;
this->imaginary = i;
}
Complex()
{
this->number = 0;
this->number = 0;
}
// Accessors
friend ostream operator<< (ostream& os, const Complex& a);
// Operator Overloads
Complex operator + (Complex b)
{
Complex c;
c.number = this->number + b.number;
c.imaginary = this->imaginary + b.imaginary;
return c;
}
private:
double number;
double imaginary;
};
ostream operator<<(ostream& output, const Complex& a)
{
output << fixed << setprecision(1) << a.number << " + " << a.imaginary << "i";
return output;
}
}
You need to return the std::ostream by reference. That means you need
namespace N
{
class Complex
{
public:
friend std::ostream& operator<< (std::ostream& os, const Complex& a);
// ^^^^^^^^^^^^^^
private:
// ...
};
std::ostream& operator<<(std::ostream& output, const Complex& a)
//^^^^^^^^^^^^
{
return output << std::fixed << std::setprecision(1)
<< a.number << " + " << a.imaginary << "i";
}
}
This is because, the std::ostream is non-copyable:
protected:
basic_ostream( const basic_ostream& rhs ) = delete; (2) (since C++11)
When you return by non-reference, it will be return by copy in operator<<, which required the copy constructor call. Since it is deleted, you get the error.

Why is there a difference when overloading different operators?

Consider the following code snippet:
class Complex {
double real, im;
public:
Complex(double real, double im) {
this->real = real;
this->im = im;
}
Complex operator + (Complex const& sec) {
Complex ret(real + sec.real, im + sec.im);
return ret;
}
friend ostream& operator<<(ostream& os, const Complex& com);
};
ostream& operator << (ostream& os, const Complex& com) {
os << com.real << " " << com.im << "i";
return os;
}
Why doesn't the operator overloading of + have to be declared as friend as it will also want to access the private variables of the class from outside, similar to when overloading the << operator? At least that's what I thought but apparently this is not the case.
A member function can access all the variables of a class, public or private. You only need friend for functions or classes that aren't part of your class.

C++ operator I/O overloading

I've encountered a strange problem while overloading << operator for a Complex class (The Complex class and overload function are not complete, but the meaning should be the same - BUT if you feel there is missing some important part, just prompt me ;-) ):
class Complex {
float m_fReal;
float m_fImaginary;
public:
Complex();
Complex(float real, float imaginary);
Complex add(Complex) const;
friend std::ostream& operator<<
(std::ostream& out, Complex cComplex);
};
Overload function:
std::ostream& operator<<(std::ostream& out, Complex cComplex) {
out << cComplex.m_fReal << " " << cComplex.m_fImaginary;
return out;
}
Add function:
Complex Complex::add(Complex cComplex) const {
return Complex (m_fReal + cComplex.m_fReal,
m_fImaginary + cComplex.m_fImaginary);
}
Function call in main:
Complex x(1,1), y(2,2);
cout << "x+y=" << x.add(y) << endl;
While the above works, this does not (only parts that differ).
Declaration in Complex class:
friend std::ostream& operator<<
(std::ostream& out, Complex& cComplex);
Definition:
std::ostream& operator<<(std::ostream& out, Complex& cComplex) {
out << cComplex.m_fReal << " " << cComplex.m_fImaginary;
return out;
}
My intention was to pass the Complex class by reference. Can anybody explain to me, what went wrong in this code and why?
You need to accept the object to output by const reference. You're accepting it as a non-const reference to which the return from add cannot be bound.
std::ostream& operator<<(std::ostream& out, const Complex& cComplex) {
This design/behavior is to prevent mistakes where a function expects to mutate the value of a reference parameter, but the reference has been bound to an unnamed temporary object, in other words memory that can't be accessed again, rendering the changes pointless.
Your definition should be
std::ostream& operator<<(std::ostream& out, const Complex& cComplex) {
out << cComplex.m_fReal << " " << cComplex.m_fImaginary;
return out;
}
cComplex needs to be const qualified for you to access its private variables using "."

How to get THIS when overloading operator in C++

I'm a student learning c++. today, I was making a operator overload function to use it in 'cout'. following is a class that contains name, coordinates, etc.
class Custom {
public:
string name;
int x;
int y;
Custom(string _name, int x, int y):name(_name){
this->x = x;
this->y = y;
}
int getDis() const {
return static_cast<int>(sqrt(x*x+y*y));
}
friend ostream& operator << (ostream& os, const Custom& other);
};
ostream& operator << (ostream& os, const Custom& other){
cout << this->name << " : " << getDis() << endl;; // error
return os;
}
However, this code isn't working because of 'THIS' keyword that I was expecting it points to the object. I want to show the object's name and distance value. How can I solve it? I think it is similar with Java's toString method so that it will be able to get THIS.
Thanks in advance for your answer and sorry for poor english. If you don't understand my question don't hesitate to make a comment.
this is available only in member functions, but your operator<< is not a class member (declaring it as friend does not make it a member). It is a global function, as it should be. In a global function, just use the arguments you are passing in:
ostream& operator << (ostream& os, const Custom& other)
{
os << other.name << " : " << other.getDis() << endl;
return os;
}
Also note os replaced cout in the code above. Using cout was an error - the output operator should output to the provided stream, not to cout always.

operator<< overloading [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Operator overloading
I didn't find any thing that could help me in this subject...
I'm trying to over load the << operator, this is my code:
ostream& Complex::operator<<(ostream& out,const Complex& b){
out<<"("<<b.x<<","<<b.y<<")";
return out;
}
this is the declaration in the H file:
ostream& operator<<(ostream& out,const Complex& b);
I get this error:
error: std::ostream& Complex::operator<<(std::ostream&, const Complex&) must take exactly one argument
what and why I'm doing wrong?
thanks
your operator << should be free function, not Complex class member in your case.
If you did your operator << class member, it actually should take one parameter, which should be stream. But then you won't be able to write like
std::cout << complex_number;
but
complex_number << std::cout;
which is equivalent to
complex_number. operator << (std::cout);
It is not common practice, as you can note, that is why operator << usually defined as free function.
class Complex
{
int a, b;
public:
Complex(int m, int d)
{
a = m; b = d;
}
friend ostream& operator<<(ostream& os, const Complex& complex);
};
ostream& operator<<(ostream& os, const Complex& complex)
{
os << complex.a << '+' << complex.b << 'i';
return os;
}
int main()
{
Complex complex(5, 6);
cout << complex;
}
More info here
As noted, the streaming overloads need to to be free functions, defined outside of your class.
Personally, I prefer to stay away from friendship and redirect to a public member function instead:
class Complex
{
public:
std::ostream& output(std::ostream& s) const;
};
std::ostream& operator<< (std::ostream& s, const Complex& c)
{
return c.output(s);
}