C++ assignment operator and overloading - c++

I was wondering why the following code is being compiled successfully.
#include <iostream>
#include <cassert>
using namespace std;
class Integer{
private:
int i;
public:
Integer(int value):i(value){}
// unary or binary
const Integer operator+(const Integer& rv){
cout << "operator+"<< endl;
return Integer(i + rv.i);
}
// Binary Operator
Integer& operator+=(const Integer& rv){
cout << "operator+=" << endl;
i += rv.i;
return *this;
}
ostream& operator<<(ostream& lv){
lv << i;
return lv;
}
friend ostream& operator<< (ostream& lv, Integer& rv);
};
ostream& operator<< (ostream& lv,Integer& rv){
return lv << rv.i;
}
int main(){
cout << "using operator overloading"<< endl;
Integer c(0), a(4), b(5);
Integer d = 8;
c = a + b;
cout << c << endl;
cout << d << endl;
}
I dont understand why d = 8 is possible. d is a user defined type. I did not overloaded the assignment oeprator for the Integer class. Is there a default overloaded operator?

You have not declared the Integer constructor explicit, so it acts as an implicit conversion from int to Integer.
If you declare your constructor
explicit Integer(int value);
the compiler fires the error:
error: conversion from ‘int’ to non-scalar type ‘Integer’ requested

Your constructor defines conversion from int to Integer
Integer(int value):i(value){}

I dont understand why d = 8 is possible. d is a user defined type.
Just instrument your code a little more and also trace the ctor calls.
#include <iostream>
#include <cassert>
using namespace std;
class Integer{
private:
int i;
public:
Integer(int value):i(value){
cout << "Integer(int) called with " << value << endl;
}
// unary or binary
const Integer operator+(const Integer& rv){
cout << "operator+"<< endl;
return Integer(i + rv.i);
}
// Binary Operator
Integer& operator+=(const Integer& rv){
cout << "operator+=" << endl;
i += rv.i;
return *this;
}
ostream& operator<<(ostream& lv){
lv << i;
return lv;
}
friend ostream& operator<< (ostream& lv, Integer& rv);
};
ostream& operator<< (ostream& lv,Integer& rv){
return lv << rv.i;
}
int main(){
Integer d = 8;
cout << d << endl;
}
output:
Integer(int) called with 8
8
live at Coliru's
The presumed assignment of the immediate 8 in fact causes the non-explicit Integer(int) ctor to be called with 8 as its argument.

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.

How to rectify private error while using Friend Function in C++?

Getting this error while using friend function in C++ : error: ‘int complex::a’ is private within this context. How will I rectify this error? I have created one complex class and while learning a friend function, i get to know that friend function can access private member functions too. But in this code, this error pops out. Thanks in advance.
#include <iostream>
using namespace std;
class complex{
private:
int a, b;
public:
void setNumber(int x,int y){a=x;b=y;}
void getNumber(){cout << "\n a="<< a << "b=" << b; }
friend ostream& operator <<(ostream&, complex);
friend istream& operator >>(istream&, complex&);
};
ostream& operator <<(ostream &dout, complex c){
cout << "a=" << c.a;
cout << "b=" << c.b;
return (dout);
}
istream& operator <<(istream &din, complex &c){
cin>>c.a>>c.b;
return (din);
}
int main(){
complex c1;
cin >> c1;
cout << c1;
return 0;
}
change this
ostream& operator <<(ostream &dout, complex c)
{
cout << "a=" << c.a;
cout << "b=" << c.b;
return (dout);
}
istream& operator <<(istream &din, complex &c)
{
cin>>c.a>>c.b;
return (din);
}
to
ostream& operator <<(ostream &dout, const complex& c)
{
dout << "a=" << c.a;
dout << "b=" << c.b;
return (dout);
}
istream& operator >>(istream &din, complex &c)
{
din>>c.a>>c.b;
return (din);
}

Overloaded 'operator++' must be a unary or binary operator (has 3 parameters)

I have a header file and a .cpp file. I am trying to implement a prefix and postfix operator overload but I keep getting this error when setting up the overload.
fraction.h
#ifndef FRACTION_H
#define FRACTION_H
#include <iostream>
using namespace std;
class Fraction
{
public:
Fraction();
Fraction(int, int);
int getTop() {return m_top;}
int getBottom() {return m_bottom;}
void set(int t, int b) {m_top=t; m_bottom=b; reduce();
}
protected:
private:
void reduce();
int gcf(int, int);
int m_top;
int m_bottom;
};
Fraction& operator ++ (Fraction);
Fraction operator++(Fraction, int);
#endif
Main.cpp
#include <iostream>
using namespace std;
#include "fraction.h"
int main {
cout << "The fraction is" << f;
cout << "The output of ++f is " << (++f) << endl;
cout << "The fraction is" << f;
cout << "The output of f++ is " << (f++) << endl;
cout << "The fraction is" << f;
return 0;
}
Fraction& Fraction::operator ++ (Fraction){
// Increment prefix
m_top += m_bottom;
return *this;
}
Fraction Fraction::operator ++ (Fraction, int){
//Increment postfix
}
These are the two errors I get:
prefix error: "Parameter of overloaded post-increment operator must have type 'int' (not 'Fraction')"
postfix error: "Overloaded 'Operator++' must be a unary or binary operator (has 3 parameters)"
Is the prefix error actually an error with my ide? I know it must be 'int' for post-increment, but I am trying to do a pre-increment. I use xcode.
You declared the operators outside the class as non-class functions
Fraction& operator ++ (Fraction);
Fraction operator++(Fraction, int);
however then you are trying to define them like class member functions
Fraction& Fraction::operator ++ (Fraction){
// Increment prefix
m_top += m_bottom;
return *this;
}
Fraction Fraction::operator ++ (Fraction, int){
//Increment postfix
}
Either declare them as class member functions the following way
class Fraction
{
public:
Fraction & operator ++();
Fraction operator ++( int );
//...
And in this case the definition for example of the preincrement operator can look like
Fraction & Fraction::operator ++(){
// Increment prefix
m_top += m_bottom;
return *this;
}
Or declare them as non-class function that are friends of the class because they need to have access to private data members of the class
class Fraction
{
public:
friend Fraction & operator ++( Fraction & );
friend Fraction operator ++( Fraction &, int );
//...
And in this case the definition for example of the preincrement operator can look like
Fraction & operator ++( Fraction &f ){
// Increment prefix
f.m_top += f.m_bottom;
return f;
}
You declared the functions as free functions
Fraction& operator ++ (Fraction);
Fraction operator++(Fraction, int);
but you are defining them as member functions.
Fraction& Fraction::operator ++ (Fraction){ ... }
Fraction& Fraction::operator ++ (Fraction, int){ ... }
Since member functions have an implicit this parameter, your member functions have three parameters (this, Fraction, and int).
Decide whether you want the functions to be free or member. If you want them to be free, then define them as free rather than member. If you want them to be member, then declare them as member and adjust the declarations as noted by #crayzeewulf above.
A member function has an implicit *this pointer which always points to the class object the member function is working on. The parameter we had to list explicitly in the friend function version (which doesn’t have a *this pointer) becomes the implicit *this parameter in the member function version.
Try making it a non member function.Then you can pass the parameter
Otherwise remove the parameter.
int main() {
Fraction f;
cout << "The fraction is" << f;
cout << "The output of ++f is " << (++f) << endl;
cout << "The fraction is" << f;
cout << "The output of f++ is " << (f++) << endl;
cout << "The fraction is" << f;
return 0;
}
Fraction& Fraction::operator++ ()
{
// Increment prefix
m_top += 1;
return *this;
}
const Fraction Fraction::operator++ (int)
{
//Increment postfix
Fraction temp = *this;
++(*this);
return temp;
}
ostream& operator<<(ostream &os, const Fraction& f)
{
os << f.m_top << endl;
return os;
}
Fraction::Fraction(const Fraction& f)
{
m_top = f.m_top;
m_bottom = f.m_bottom;
}
Fraction::Fraction(int t, int b) :m_top(t), m_bottom(b){}
Fraction::Fraction() : m_top(1), m_bottom(1){}
class Fraction
{
public:
Fraction();
Fraction(int, int);
Fraction(const Fraction& f);
int getTop() { return m_top; }
int getBottom() { return m_bottom; }
void set(int t, int b) {
m_top = t; m_bottom = b; reduce();
}
Fraction& operator ++ ();
const Fraction operator++(int);
friend ostream& operator<<(ostream &os,const Fraction& f);
protected:
private:
void reduce();
int gcf(int, int);
int m_top;
int m_bottom;
};
#endif

Problems with ostream

I'm working in a Big Integer implementation in C++ and I'm trying to use cout with my BigInt class. I already overloaded the << operator but it doesn't work in some cases.
Here is my code:
inline std::ostream& operator << (ostream &stream, BigInt &B){
if (!B.getSign()){
stream << '-';
}
stream << B.getNumber();
return stream;
}
The code above works with:
c = a + b;
cout << c << endl;
But fails with:
cout << a + b << endl;
In the first case the program runs fine, but in the second the compiler gave an error:
main.cc: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
It's possible to overload the << operator for function in both cases?
Methods:
string getNumber ();
bool getSign ();
string BigInt::getNumber (){
return this->number;
}
bool BigInt::getSign (){
return this->sign;
}
As chris already pointed out in comments very quickly (as usual), you have a temporary created in here:
cout << a + b << endl;
You cannot bind that to a non-const reference. You will need to change the signature of your operator overloading by adding the const keyword to the reference.
This code works for me with a dummy BigInt implementation (as you have not shared yours):
#include <iostream>
using namespace std;
class BigInt
{
public:
bool getSign() const { return true; }
int getNumber() const { return 0; }
const BigInt operator+(const BigInt &other) const {}
};
inline std::ostream& operator << (ostream &stream, const BigInt &B){
// ^^^^^
if (!B.getSign()){
stream << '-';
}
stream << B.getNumber();
return stream;
}
int main()
{
BigInt a, b, c;
c = a + b;
cout << c << endl;
cout << a + b << endl;
return 0;
}
But yeah, I agree that the error message is not self-explanatory in this particular case.
Change
inline std::ostream& operator << (ostream &stream, BigInt &B){
to
inline std::ostream& operator << (ostream &stream, BigInt const& B){
c can be a used where BiInt& is expected but a+b cannot be because a+b is a temporary. But it can be used where BigInt const& is expected.

How to overload << operator without friend function

I am trying to overload << operator to print Currency (user defined type)
#include <iostream>
using namespace std;
struct Currency
{
int Dollar;
int Cents;
ostream& operator<< (ostream &out)
{
out << "(" << Dollar << ", " << Cents << ")";
return out;
}
};
template<typename T>
void DisplayValue(T tValue)
{
cout << tValue << endl;
}
int main() {
Currency c;
c.Dollar = 10;
c.Cents = 54;
DisplayValue(20); // <int>
DisplayValue("This is text"); // <const char*>
DisplayValue(20.4 * 3.14); // <double>
DisplayValue(c); // Works. compiler will be happy now.
return 0;
}
But getting the following error.
prog.cpp: In instantiation of ‘void DisplayValue(T) [with T = Currency]’:
prog.cpp:34:16: required from here
prog.cpp:22:9: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
cout << tValue << endl;
^
In file included from /usr/include/c++/4.8/iostream:39:0,
from prog.cpp:1:
/usr/include/c++/4.8/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Currency]’
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
Can anyone help me if i am missing any thing or doing anything wrong here?
First you need to fix the operator by adding Currency const& c as the second parameter (as it come s on the right hand side).
Then you have two options:
1: Add Friend
struct Currency
{
int Dollar;
int Cents;
friend ostream& operator<< (ostream &out, Currency const& c)
{
return out << "(" << c.Dollar << ", " << c.Cents << ")";
}
};
2: Move the definition outside the class
struct Currency
{
int Dollar;
int Cents;
};
ostream& operator<< (ostream &out, Currency const& c)
{
return out << "(" << C.Dollar << ", " << c.Cents << ")";
}
Either works and is fine.
Personally I like option-1 as it documents the tight coupling of the output operator to the class that it is outputting. But this is such a simple case that either works just fine.
The reason that it can not be a member is that the first parameter is a stream (the left hand side value of the operator is the first parameter). This does not work for members as the first parameter is the hidden this parameter. So technically you could add this method to std::ostream. Unfortunately you don't have accesses (and not allowed to) modify std::ostream. As a result you must make it a free standing function.
Example showing it can be a member:
struct X
{
std::ostream operator<<(int y)
{
return std::cout << y << " -- An int\n";
}
};
int main()
{
X x;
x << 5;
}
That works fine here.
This is because the compiler translates
x << 5;
into
// not real code (pseudo thought experiment code).
operator<<(x, 5)
// Equivalent to:
X::operator<<(int y)
// or
operator<<(X& x, int y)
Because x has a member function operator<< this works fine. If x did not have a member function called operator<< then the compiler would look for a free standing function that takes two parameters with X as the first and int as the second.
You don't put it into your class, you put if afterwards. Since your members are public there is no need to declare it a friend:
struct Currency
{
int Dollar;
int Cents;
};
ostream& operator<< (ostream &out, const Currency& c)
{
out << "(" << c.Dollar << ", " << c.Cents << ")";
return out;
}
Overload it like below, and put it outside of class declaration (you don't need friendship!):
ostream& operator<< (ostream &out, const Currency &c)
{ //^^^^^^^^^^^^^^^^
out << "(" << c.Dollar << ", " << c.Cents << ")";
return out;
}
Funny thing with your code is, you have to use the operator like this:
c << cout; // !!
The way you've written your inserter method, the only way to get it to work would be to do:
c << std::cout;
But instead, if you know your inserters won't need to access any private variables, simply do as the other answers say and create a global function that takes both arguments:
std::ostream& operator <<(std::ostream& os, const Currency& c);
#include<iostream>
using namespace std;
class myclass
{
int x;
public:
myclass() //constructor
{
x=5;
}
friend ostream& operator<<(ostream &outStreamObject,myclass &object); //standard way
void operator<<(ostream &outStreamObject) //Another way.
{
outStreamObject<<this->x;
}
};
ostream& operator<<(ostream &outStreamObject,myclass &object)
{
cout<<object.x;
return outStreamObject;
}
int main()
{
//standard way of overload the extraction operator
myclass object1,object2;
cout<<object1<<" "<<object2;
cout<<endl;
//overloading the extraction operator with using friend function
object1.operator<<(cout);
return 0;
}
It is not at all necessary that the insertion and the extraction operators can be overloaded only by using the friend function.
The above code overloads the extraction operator with and without the friend function. The friend function implementation is favoured because cout can be used the way it is used for other datatypes.
Similary you can overload the insertion operator.
You need to make it friend :
Also you need to give it the right arguments. an ostream and the currency.
friend ostream& operator<< (ostream& stream, const Currency& c )
{
stream << "(" << c.Dollar << ", " << c.Cents << ")";
return stream;
}
Edit:
As you can see in the comments, you don't have to make it friend. You can put it outside the structure.
Currency c;
c.Dollar = 10;
c.Cents = 54;
DisplayValue(c); // Works. compiler will be happy now.