Insertion and Extraction operator doesn't work - c++

Was just playing with operator overloading and couldn't find out whats wrong with the below code -
#include <iostream>
class Holder
{
public:
std::string name;
int data;
};
std::istream operator>>(std::istream& is, Holder &h)
{
std::cout<<"Enter name = "<<std::endl;
std::cin>>h.name;
std::cout<<"Enter data = "<<std::endl;
std::cin>>h.data;
return is;
}
std::ostream operator<<(std::ostream& os, Holder const &h)
{
std::cout<<"Name = "<<h.name<<std::endl;
std::cout<<"Data = "<<h.data<<std::endl;
return os;
}
int main(int argc, char **argv) {
Holder h;
std::cin>>h;
std::cout<<h;
}
The error my MinGW compiler gives is -
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/ios:45:0,
from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/ostream:40,
from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/iostream:40,
from ..\src\Main.cpp:1:
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/ios_base.h: In copy constructor 'std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)':
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/ios_base.h:788:5: error: 'std::ios_base::ios_base(const std::ios_base&)' is private
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/bits/basic_ios.h:64:11: error: within this context
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/iostream:41:0,
from ..\src\Main.cpp:1:
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/istream: In copy constructor 'std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)':
c:\mingw\bin\../lib/gcc/mingw32/4.6.1/include/c++/istream:57:11: note: synthesized method 'std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)' first required here
..\src\Main.cpp: In function 'std::istream operator>>(std::istream&, Holder&)':
..\src\Main.cpp:18:9: note: synthesized method 'std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)' first required here

Return by reference:
std::istream& operator>>(std::istream& is, Holder &h)
std::ostream& operator<<(std::ostream& os, Holder const &h)
//^
as streams are not copyable.

Related

How does cin read strings into an object of string class?

Reading some documentation online I found that istream class was part of C++ long before the string class was added. So the istream design recognizes basic C++ types such as double and int, but it is ignorant of the string type. Therefore, there are istream class methods for processing double and int and other basic types, but there are no istream class methods for processing string objects.
My question is if there are no istream class methods for processing string objects, why this program works and how ?
#include <iostream>
int main(void)
{
std::string str;
std::cin >> str;
std::cout << str << std::endl;
return 0;
}
This is possible with the use operator overloading. As shown in the below example, you can create your own class and overload operator>> and operator<<.
#include <iostream>
class Number
{
//overload operator<< so that we can use std::cout<<
friend std::ostream& operator<<(std::ostream &os, const Number& num);
//overload operator>> so that we can use std::cin>>
friend std::istream &operator>>(std::istream &is, Number &obj);
int m_value = 0;
public:
Number(int value = 0);
};
Number::Number(int value): m_value(value)
{
}
std::ostream& operator<<(std::ostream &os, const Number& num)
{
os << num.m_value;
return os;
}
std::istream &operator>>(std::istream &is, Number &obj)
{
is >> obj.m_value;
if (is) // check that the inputs succeeded
{
;//do something
}
else
{
obj = Number(); // input failed: give the object the default state
}
return is;
}
int main()
{
Number a{ 10 };
std::cout << a << std::endl; //this will print 10
std::cin >> a; //this will take input from user
std::cout << a << std::endl; //this will print whatever number (m_value) the user entered above
return 0;
}
By overloading operator>> and operator<<, this allows us to write std::cin >> a and std::cout << a in the above program.
Similar to the Number class shown above, the std::string class also makes use of operator overloading. In particular, std::string overloads operator>> and operator<<, allowing us to write std::cin >> str and std::cout << str, as you did in your example.
Because std::string overload the >> and << operator to return the type std::istream and std::ostream
How they overload it, you can look in this link that Mat gives.
You can create your own class and overload operators, too. Here is an example:
class MyClass
{
int numberOne;
double numberTwo;
public:
friend std::ostream& operator<<(std::ostream &out, const MyClass& myClass);
friend std::istream& operator>> (std::istream& in, MyClass& myClass);
};
// Since operator<< is a friend of the MyClass class, we can access MyClass's members directly.
std::ostream& operator<<(std::ostream &out, const MyClass& myClass)
{
out << myClass.numberOne << ' ' << myClass.numberTwo;
return os;
}
// Since operator>> is a friend of the MyClass class, we can access MyClass's members directly.
std::istream& operator>> (std::istream& in, MyClass& myClass)
{
in >> myClass.numberOne;
in >> myClass.numberTwo;
return in;
}
int main()
{
MyClass myClass;
std::cin >> myClass;
std::cout << myClass;
}
Because of operator overloading.
In your case, including <iostream> will include <string>, a specialization of std::basic_string. And std::basic_string has the non-member functions operator<< and operator>> defined.
Similarly, you can also overload operator<< and operator>> for your own custom types.

Does not name a type error on constructor and destructor

I'm trying to understand why this class is asking for a type on constructor and destructor, from what I've seen it seems that it would be something wrong with my class declaration but, it seems like I wrote it right. Also overloading operator<< seems to just return an error because it is also not recognized.
Board.h
#ifndef BOARD_H_
#define BOARD_H_
#include <string>
#include <iostream>
#include "Board.cpp"
class Board{
public:
Board(std::string p1_token, std::string p2_token, std::string blank_token);
~Board();
void clear();
//Accessors
int numRows();
int numColumns();
int numTokensInColumn(int colNum);
// bool is true if player 1 turn, false if player 2
// Returns blank if no one wins, winner token if some wins
std::string insert(int column, bool turn);
//ostream& operator<<(ostream& os, const Board& bd);
private:
std::string p1_token;
std::string p2_token;
std::string blank_token;
std::string ** ptr_columns;
int amt_cols;
int amt_rows;
};
#endif
Board.cpp
#include "Board.h"
#include <iostream>
#include <string>
Board::Board(std::string p1, std::string p2, std::string blank){
p1_token = p1;
p2_token = p2;
blank_token = blank;
amt_cols = 4;
amt_rows = 5;
ptr_columns = new std::string*[amt_cols];
//Right now all these are uniform
//Definition of order
//left-right first order of columns 0-end(4-1)
//Then
//down-up for each index of column ^, 0-end(5-1)
for(int I=0; I<amt_cols-1; ++I){
ptr_columns[I] = new std::string[5];
for(int V=0; V<amt_rows-1; ++V){
ptr_columns[I][V] = blank_token;
}
}
}
Board::~Board(){
delete [] ptr_columns;
}
ostream& Board::operator<<(ostream& os, const Board& bd){
for(int V = amt_rows-1; V>=0; --V){
for(int I = 0; I<amt_cols-1;++I){
os << bd.ptr_columns[I][V] << " ";
}
os << "\n";
}
return os;
}
Errors
Board.cpp:5:1: error: ‘Board’ does not name a type
Board::Board(std::string p1, std::string p2, std::string blank){
^~~~~
Board.cpp:25:1: error: ‘Board’ does not name a type
Board::~Board(){
^~~~~
Board.cpp:29:1: error: ‘ostream’ does not name a type
ostream& Board::operator<<(ostream& os, const Board& bd){
^~~~~~~
In file included from Board.cpp:1:0:
Board.h:19:2: error: ‘ostream’ does not name a type
ostream& operator<<(ostream& os, const Board& bd);
^~~~~~~
Board.cpp:29:1: error: ‘ostream’ does not name a type
ostream& Board::operator<<(ostream& os, const Board& bd){
^~~~~~~
In file included from Board.h:5:0,
from connect_four_main.cpp:3:
Board.cpp:5:1: error: ‘Board’ does not name a type
Board::Board(std::string p1, std::string p2, std::string blank){
^~~~~
Board.cpp:25:1: error: ‘Board’ does not name a type
Board::~Board(){
^~~~~
Board.cpp:29:1: error: ‘ostream’ does not name a type
ostream& Board::operator<<(ostream& os, const Board& bd){
^~~~~~~
In file included from connect_four_main.cpp:3:0:
Board.h:19:2: error: ‘ostream’ does not name a type
ostream& operator<<(ostream& os, const Board& bd);
You have a number of issues.
Don't #include .cpp files.
Your << operator should be declared as a free function not a member function, declare it as a friend instead:
class Board{
...
friend std::ostream& operator<<(std::ostream& os, const Board& bd);
...
}
Your operator uses some member variables from this rather than bd, the correct implementation is:
std::ostream& operator<<(std::ostream& os, const Board& bd){
for(int V = bd.amt_rows-1; V>=0; --V){
for(int I = 0; I<bd.amt_cols-1;++I){
os << bd.ptr_columns[I][V] << " ";
}
os << "\n";
}
return os;
}

expected a parameter in the header

I am trying to read and display the contents of a file named myDocument.txt, but I always get the following error with my header file.
./ReadDocument.h:22:24: error: expected parameter declarator std::ifstream myflux("myDocument.txt");
What's going on?
Here is my ReadDocument.h:
class ReadDocument{
public:
ReadDocument(); //empty constructor
ReadDocument(const std::string& fileName); //constructor
void documentContent();
friend std::ostream& operator <<(std::ostream& os, const ReadDocument& d);
std::list<std::string> myList;
std::ifstream myflux("myDocument.txt");
if(myflux){
//Getting the words from the file string by string
std::string data;
while(myflux>>data){
myList.push_back(data);
}
myflux.close();
}
else{
std::string message = "\t\tERROR ==> This file doesn't exist.";
throw FileDoesntExistException(message);
}
};
Here is my ReadDocument.cpp:
#include "ReadDocument.h"
ReadDocument::ReadDocument(){}
void ReadDocument::documentContent(){}
std::ostream& operator <<(std::ostream& os, const ReadDocument& d){
for(std::list <std::string> :: const_iterator it = ReadDocument::myList.begin(); it!=ReadDocument::myList.end(); it++)
std::cout<<*it<<std::endl;
return os;
}
And this is my UseReadDocument.cpp
#include "ReadDocument.h"
int main(){
ReadDocument rd("test.txt");
std::cout<<rd<<std::endl;
return 0;
}
I tried renamed the file and still the same problem.
I put it in the class, and doesn't change anything.
I always have the same error coming out.
and yes it is my entire code
The part of your class after myflux is not in a method.
Did you want to put the code in the function documentContent, like this?
ReadDocument.h:
class ReadDocument{
public:
ReadDocument(); //empty constructor
ReadDocument(const std::string& fileName); //constructor
void documentContent();
friend std::ostream& operator <<(std::ostream& os, const ReadDocument& d);
std::list<std::string> myList;
std::ifstream myflux("myDocument.txt");
};
ReadDocument.cpp:
#include "ReadDocument.h"
ReadDocument::ReadDocument(){}
void ReadDocument::documentContent(){
if(myflux){
//Getting the words from the file string by string
std::string data;
while(myflux>>data){
myList.push_back(data);
}
myflux.close();
}
else{
std::string message = "\t\tERROR ==> This file doesn't exist.";
throw FileDoesntExistException(message);
}
}
std::ostream& operator <<(std::ostream& os, const ReadDocument& d){
for(std::list <std::string> :: const_iterator it = ReadDocument::myList.begin(); it!=ReadDocument::myList.end(); it++)
std::cout<<*it<<std::endl;
return os;
}
By the way, you should avoid creating an empty constructor and filling it with nothing.
Since C++11 you should write ReadDocument() = default; in your header and remove ReadDocument::ReadDocument(){} from the cpp.
With your class your are declaring two public variables and trying to give each instance of your class these default characteristics. The solution in to put the default conditions in the default constructor as follows:
class ReadDocument{
private:
std::list<std::string> myList; //moved member variables to private
std::ifstream myflux; //part of class
public:
ReadDocument(); //empty constructor
ReadDocument(const std::string& fileName); //constructor
void documentContent();
friend std::ostream& operator <<(std::ostream& os, const ReadDocument& d);
};
Implementation:
#include "ReadDocument.h"
ReadDocument::ReadDocument()
{
myflux.open("myDocument.txt");
if(myflux){
//Getting the words from the file string by string
std::string data;
while(myflux>>data){
myList.push_back(data);
}
myflux.close();
}
else{
std::string message = "\t\tERROR ==> This file doesn't exist.";
throw FileDoesntExistException(message);
}
}
void ReadDocument::documentContent(){}
std::ostream& operator <<(std::ostream& os, const ReadDocument& d){
for(std::list <std::string> :: const_iterator it =
d.myList.begin(); it!=d.myList.end(); it++)
std::cout<<*it<<std::endl;
return os;
}
Code will now associate myflux with "myDocument.txt" and extract the file data into myList by default (unless instantiated with string parameter for use with const string& constructor) for each instance of the ReadDocument class. As well as a few other fixes in the ostream function.
P.S* Assuming this is your entire .cpp file associated with the ReadDocument class, you forgot to implement the constructor containing the const string& parameter, ReadDocument(const std::string& fileName).

Why friend function is not able to access private members of the class

While executing this program, i am getting following compilation error:
template.cpp: In function ‘std::istream& operator>>(std::istream&, currency&)’:
template.cpp:8: error: ‘int currency::doller’ is private
template.cpp:25: error: within this context
template.cpp:9: error: ‘int currency::cents’ is private
template.cpp:25: error: within this context
This is the c++ program:
#include <iostream>
using namespace std;
class currency
{
private:
int doller;
int cents;
public:
currency():doller(0),cents(0) {}
friend ostream& operator<< (ostream& stream, const currency& c );
friend istream& operator>> (istream& in, const currency& c);
/*friend istream& operator>> (istream& in, const currency& c)
{
in >> c.doller >> c.cents;
return in;
} */
};
istream& operator>> (istream& in, currency& c)
{
in >> c.doller >> c.cents;
return in;
}
ostream& operator<< (ostream& stream, const currency& c )
{
stream << "(" << c.doller << ", " << c.cents << ")";
return stream;
}
template <class T>
void function(T data)
{
cout << "i am in generalized template function: " << data << endl;
}
template<>
void function (int data)
{
cout << "This is: specialized for int" << data << endl;
}
int main()
{
currency c;
cin >> c;
function (c);
function (3.14);
function ('a');
function (12);
return 0;
}
at the same time std::ostream& operator<<(std::ostream&, const currency&) not giving any error. I want to understand is there anything wrong in the program??
Also, while i am giving the defition inside the class this is the error:
template.cpp: In function ‘std::istream& operator>>(std::istream&, const currency&)’:
template.cpp:18: error: ambiguous overload for ‘operator>>’ in ‘in >> c->currency::doller’
You have the wrong signature in your operator>> definition, which means you are declaring and defining a different operator. You need to remove the const from the friend istream& operator declaration for it to be the definition of the friend operator:
friend
istream& operator>> (istream& in, currency& c)
//
The ambiguous overload is for the same reason. You have two functions that match. The fix suggested above would solve both problems.
The signature of the operator>> does not match the one declared as friend of the class:
istream& operator>> (istream& in, currency& c); // outside class
istream& operator>> (istream& in, const currency& c); // friend class
// ^^^^^
You'll need to remove the const signature in the method declaration:
friend istream& operator>> (istream& in, currency& c);
The function that you define doesn't have the const in it, so it's not the function that you declare as friend and hence cannot access the private members. Note that declaring the currency object const doesn't make sense either, since you change it using the instream operator.

Overloading Insertion Operator in C++

I have a class in which I'm trying to overload the << operator. For some reason, it is not being overloaded.
Here is my .h file:
friend std::ostream& operator<<(std::ostream&, const course &); //course is my class object name
in my .cpp, I have this as my implementation:
std::ostream& operator<<(std::ostream &out, const course & rhs){
out << rhs.info;
return out;
}
This should be correct, but when I try to compile it, it says that cout << tmp; is not defined in ostream.
I've included iostream in my .cpp and .h
I'm been pulling my hair out trying to figure this out. Can you see anything that's wrong with this?
EDIT:
Since what I'm doing seems to be correct, here's all of my source code: http://pastebin.com/f5b523770
line 46 is my prototype
line 377 is the implementation
line 435 is where it fails when i attempt to compile it.
also, I just tried compiling it on another machine, and it gives this error instead:
course.cpp:246: error: non-member function 'std::ostream& operator<<(std::ostream&, const course&)' cannot have cv-qualifier
make: *** [course.o] Error 1
The syntax you've listed is correct, but the overloaded operator prototype has to be declared in the course definition to work properly.
course.h
class course {
public:
friend std::ostream& operator<<(std::ostream&, const course&);
private:
int info;
}
course.cpp
std::ostream& operator<<(std::ostream &out, const course &rhs){
out << rhs.info;
return out;
}
It looks fine to me. Here's my version of it:
course.h
#include <iostream>
class course
{
public:
friend std::ostream& operator<<(std::ostream&, const course &); //course is my class object name
int info;
course(){info = 10;}
};
course.cpp
#include <iostream>
#include "course.h"
std::ostream& operator<<(std::ostream &out, const course & rhs)
{
out << rhs.info;
return out;
}
main_file.cpp
#include <iostream>
#include "course.h"
int main()
{
course a;
std::cout<<a;
return 0;
}
You should include the rest of the code, I don't think we can see where the problem is.
The following trivial example works:
class course
{
public:
course(int info) : info(info) { }
int info;
friend std::ostream& operator<<(std::ostream&, const course &);
};
std::ostream& operator<<(std::ostream &out, const course & rhs)
{
out << rhs.info;
return out;
}
int main(int, char*[])
{
course tmp(3);
std::cout << tmp;
return 0;
}
I found this helpful!
My insertion and extraction operators are slightly different.
here they are defined:
friend ostream& operator<<(ostream &fout, datatype toPrint)
friend istream& operator>>(istream &fin, datatype &toReadTo)
the syntax needs to be exact.