I have the following block of code trying to overload the >> operator:
istream &operator >> (istream &stream, const Currency &obj){
cout << "Dollars: ";
stream>>obj.dollars;
cout<< "Cents: ";
stream>> obj.cents;
return stream;
}
But when I call cin>>newMoney from my main program it keeps repeating "DOLLARS:" over and over again in an endless loop like below:
Any ideas why?
I bet you have a Currency constructor that takes an 'int'. So stream>>obj.dollars; is the same as stream>>Currency(obj.dollars);. The function you pasted outputs "Dollars: " and then calls itself, outputting "Dollars: " again and then repeating forever.
I'd suggest making the constructor explicit so it doesn't misfire on you.
There is no enough information in your code (as of now). Till you post more code, all I can say is this, which is also important for you to note down: since you overload >> to take input, the object obj should be passed by non-const reference, so remove const from the second parameter, and make it look like this:
istream &operator >> (istream &stream, Currency &obj)
Related
This question already has answers here:
Can't Overload operator<< as member function
(3 answers)
Closed 8 months ago.
From c++ how to program 10th edition by deitel
//Fig. 10.3: PhoneNumber.h
//PhoneNumber class definition
#ifndef PHONENUMBER_H
#define PHONENUMBER_H
#include <iostream>
#include <string>
class PhoneNumber
{
friend std::ostream& operator<<(std::ostream&, const PhoneNumber&);
friend std::istream& operator>>(std::istream&, PhoneNumber&);
private:
std::string areaCode; //3-digit area code
std::string exchange; //3-digit exchange
std::string line; //4-digit line
};
#endif // PHONENUMBER_H
//Fig. 10.4: PhoneNumber.cpp
//Overloaded stream insertion and stream extraction operators
#include <iomanip>
#include "PhoneNumber.h"
using namespace std;
//overloaded stream insertion operator; cannot be a member function
//if we would like to invoke it with cout << somePhoneNumber;
ostream& operator<<(ostream& output, const PhoneNumber& number)
{
output << "Area code: " << number.areaCode << "\nExchange: "
<< number.exchange << "\nLine: " << number.line << "\n"
<< "(" << number.areaCode << ") " << number.exchange << "-"
<< number.line << "\n";
return output; //enables cout << a << b << c;
}
//overloaded stream extraction operator; cannot be a member function
//if we would like to invoke it with cin >> somePhoneNumber;
istream& operator>>(istream& input, PhoneNumber& number)
{
input.ignore(); //skip (
input >> setw(3) >> number.areaCode; //input area code
input.ignore(2); //skip ) and space
input >> setw(3) >> number.exchange; //input exchange
input.ignore(); //skip dash (-)
input >> setw(4) >> number.line; //input line
return input; //enables cin >> a >> b >> c
}
//Fig. 10.5: fig10_5.cpp
//Demonstrating Class PhoneNumber's overloaded stream insertion
//and stream extraction operators.
#include <iostream>
#include "PhoneNumber.h"
#include <string>
using namespace std;
int main()
{
PhoneNumber phone; //create object phone
cout << "Enter phone number in the form (555) 555-5555:" << endl;
//cin >> phone invokes operator>> by implicitly issuing
//the non-member function call operator>>(cin, phone)
cin >> phone;
//cout << phone invokes operator<< bby implicitly issuing
//the non-member function call operator<<(cout, phone)
cout << phone << endl;
}
I understand from the book that the overloaded operator function for binary operator can be member function only when the left operand is an object of the class in which the function is a member because the member function can only be accessed by left operand which is the object of the class.
however I don't understand this part
" The overloaded stream insertion operator (<<) is used in an expression in which the
left operand has type ostream&, as in cout << classObject. To use the operator in this
manner where the right operand is an object of a user-defined class, it must be overloaded
as a non-member function. To be a member function, operator << would have to be a
member of class ostream. This is not possible for user-defined classes, since we are not
allowed to modify C++ Standard Library classes. "
my question is
whether the stream extraction and insertion operator is part of the ostream and istream respectively?
what does the part highlighted in bold mean?
My guess is that we cannot add user defined function into the C++ Standard Library class but the part in bold makes me kind of confused. do we have to add the operator << as member of class ostream to make the overloaded operator function as member function of ostream?
I always thought that stream << and >> operator were part of ostream and istream respectively.
Correct me if I am wrong. thank you in advance.
No, not for regular user defined types. The functions you made into friends in your class definition are free functions:
std::ostream& operator<<(std::ostream&, const PhoneNumber&);
std::istream& operator>>(std::istream&, PhoneNumber&);
std::basic_ostream does have some operator<< member overloads for fundamental types, such as int, and some types defined in the standard library though. If you inherit from some of those standard types, like std::basic_streambuf<CharT, Traits>, you will be able to use the basic_ostream::operator<< member overloads for those types.
It means that you are not allowed to modify the definition of std::basic_ostream to add std::basic_ostream& operator<<(const PhoneNumber&) as a member function.
You might have already read about overloading. There is not one function called operator<<, there are multiple. Some of those are class members, others aren't. The compiler will choose the right operator<< based on the two arguments.
When the compiler looks for overloads of operator<<, it will check class methods of the object on the left-hand side only. (If that's even a class. In 1<<3==8 the arguments are ints). For that reason, when the compiler sees std::cout << YourClass{} it won't look for YourClass::operator<<(ostream&).
If you wrote YourClass{} << std::cout (VERY unusual), the compiler would look in YourClass. Rules are rules, and there is no hard rule that forbids that order. But it would break the usual chaining of std::cout << a << b << c, so it's very inconvenient. So to make the usual chaining work, we do it as your textbook tells you.
I've been trying to overload the >> operator. I have a class that has two private variables:
Class Complex
{
private:
double real;
double imaginary;
};
In addition I have a friend function that overloads the >> operator:
friend istream & operator>>(istream &is, Complex &c)
In the implementation of the function I've tried many ways to write into the variable of object c but I keep getting an error no operator >> matches these operands
I looked around and read that I need to write into a reference of the variable, so I tried the following:
istream & operator>>(istream &is, Complex &c)
{
using std::cout;
double &r = c.real;
cout << "real: " << is >> r;
return is;
}
However this still gives me the same error.
I'm slightly confused as I tried is >> c.real and didn't work.
On one of the answers in a similar SO question, someone suggested writing into a local variable and setting the object variable it, something like:
double d;
cin >> d;
setReal(d);
I'm trying to find a more simpler way to achieve this rather than using a method or setting the variable to a local one.
The solution could be a simple one, but I'm really just a beginner in C++, so please take it easy on me :P.
Test case:
using std::cin;
Complex c;
cin >> c;
Exact error message:
Error 1 error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::basic_ostream<_Elem,_Traits>' (or there is no acceptable conversion)
The error is on this line:
cout << "real: " << is >> r;
This is interpreted as
((cout << "real: ") << is) >> r
The problem here is that you can't have a line like this where you switch from outputting to cout and start reading from is. A better way to do this would be
cout << "real: ";
is >> r;
That said, this is a very bad idea. You should not have operator >> display a prompt, since it means that if you want to read in an object of your type from a file, every time you do so you will get the prompt "real" displayed on-screen. You should have operator >> just read the representation, and explicitly prompt before reading if that's what you want to do.
Hope this helps!
The error is on this line:
cout << "real: " << is >> r;
Did you mean to use << instead of >> on that last one? Since you used >>, it's trying to write "is" into cout, but there is no overload of operator<< that takes a basic_ostream and a basic_istream.
So I'm failing a simple input test for one of assignment questions. I'm to parse two integers separated by a white space. The two integers are used in the private members num and denom of the Rationalnumber type I have defined as a class. Is there something obviously unconventional I am using in or missing from this code? This code works for all my tests.
std::istream &operator>>( std::istream &is, Rationalnumber &r ) {
Rationalnumber::in++; // increment counter
// get the num
string n;
getline(cin,n,' ');
stringstream ssnum(n);
ssnum >> r.num;
// get the denom
string d;
getline(cin,d,'\n');
stringstream ssdenom(d);
ssdenom >> r.denom;
return is;
}
Your code fails in, at least, two obvious ways:
If a different whitespace than space is used, e.g., '\t', it isn't recognized by your code.
The input operator doesn't indicate failure when it is given invalid inputs, e.g., when the input is "a b" rather than numbers.
Conventionally, when input fails, the valuevread remains unchanged. This is also not true for your implementation. To fix things up the code can actually be simplified and made a lot fadter in the process. As this is clearly a homework assignment I don't think it is appropriate to provide the code, though.
This code passes the test!:
std::istream &operator>>( std::istream &is, Rationalnumber &r ) {
Rationalnumber::in++; // increment counter
int in;
is >> in;
r.numerator(in);
is >> in;
r.denominator(in);
return is;
}
Hello im having problems reading lines (ignore space characters) in an overloaded Extraction operator
this is my code any assistance would be great
istream& operator>>(istream& is, CreditAccount& Cred){
cout << "Name: ";
is.getline(Cred.name, 256);
}
my error is as follows
error: no matching function for call to ‘std::basic_istream<char, std::char_traits<char> >::getline(std::string&, int)’
we need to know the the type of Cred::name, however from your error it appears to be a std::string. the correct function to use is:
#include <string> //for std::getline
istream& operator>>(istream& is, CreditAccount& Cred){
std::cout << "Name: ";
std::getline(is, Cred.name);
return is;
}
I would also stress, that if you are using std::cout to prompt the user for input you are not using the stream extraction operator properly, it is for basic serialisation and de serialisation of an objects state. Not for user interaction. I personally would just have a "produce_credit_account()" function or the like.
EDIT: to clear std::cin
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
Here are the instructions verbatim:
String insertion/extraction operators (<< and >>) need to be overloaded within the MyString object. These operators will also need to be capable of cascaded operations (i.e., cout << String1 << String2 or cin >> String1 >> String2). The string insertion operator (>>) will read an entire line of characters that is either terminated by an end-of-line character (\n) or 256 characters long. An input line that exceeds 256 characters will be limited to only the first 256 characters.
With that, this is the code I've gotten thus far:
in my .cpp file:
istream& MyString::operator>>(istream& input, MyString& rhs)
{
char* temp;
int size(256);
temp = new char[size];
input.get(temp,size);
rhs = MyString(temp);
delete [] temp;
return input;
}
in my .h file:
istream& operator>>(istream& input, MyString& rhs);
call from main.cpp file:
MyString String1;
const MyString ConstString("Target string"); //Test of alternate constructor
MyString SearchString; //Test of default constructor that should set "Hello World"
MyString TargetString (String1); //Test of copy constructor
cout << "Please enter two strings. ";
cout << "Each string needs to be shorter than 256 characters or terminated by
/.\n" << endl;
cout << "The first string will be searched to see whether it contains exactly the second string. " << endl;
cin >> SearchString >> TargetString; // Test of cascaded string-extraction operator<<
The error that I get is: istream& MyString::operator>>(std::istream&, MyString&)â must take exactly one argument
How can I correct this? I am super confused on how to do this without BOTH the rhs and input
You have to create the operator>> as a non-member function.
As it is now, your function expects three arguments: the implicit invoking object, the istream&, and the MyString& rhs. However, since operator>> is a binary operator (it takes exactly two arguments) this won't work.
The way to do this is to make it a non-member function:
// prototype, OUTSIDE the class definition
istream& operator>>(istream&, MyString&);
// implementation
istream& operator>>(istream& lhs, MyString& rhs) {
// logic
return lhs;
}
And doing it that way (non-member function) is the way you have to do all operators where you want your class to be on the right side, and a class that you can't modify on the left side.
Also note that if you want to have that function access private or protected members of your objects, you have to declare it friend in your class definition.