C++ overloading the ostream and istream operators - c++

The aim of this code is to read the file containing the name, dollars in billions and the country which are separated by tabs.
I need to create a class Billionaire and overload the ostream and istream operators to conveniently
read the file into a vector and write the content to the output. And then create a map which maps the country string to a pair. The pair contains a copy of the first
billionaire of every country from the list and a counter to count the number of billionaires per
country. However, I cannot overload stream and stream operators.
I've tried to overload these operators in Billionaire class but I am ending up with errors.
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <iterator>
#include <fstream>
#include <istream>
#include <ostream>
using namespace std;
class Billionaire{
//overload the ostream and istream operators to conveniently
//read the file into a vector and write the content to the output
public :
friend ostream &operator<<(ostream &stream, Billionaire o);
friend istream &operator>>(istream &stream, Billionaire &o);
};
int main(){
std::ifstream stream("Forbes2018.txt");
if(!stream){
cout << " WARNING : File not found !" << endl ;
}
vector <Billionaire> billionaires;
copy (istream_iterator<Billionaire>( stream ),
istream_iterator<Billionaire>() , back_inserter( billionaires ));
copy (billionaires.begin () , billionaires.end () ,
ostream_iterator < Billionaire >( cout , "\n"));
map < string , pair < const Billionaire , size_t >> m;
}
I am having 2 errors:
:-1: error: symbol(s) not found for architecture x86_64
:-1: error: linker command failed with exit code 1 (use -v to see invocation)

Your overload attempt is a good start: you have announced to the compiler that there will be an overload:
friend ostream &operator<<(ostream &stream, Billionaire o);
friend istream &operator>>(istream &stream, Billionaire &o);
Unfortunately, something is missing. This is what the linker message says. You still need to tell the compiler how this overload looks like:
ostream &operator<<(ostream &stream, Billionaire o) {
// put your code here
...
return stream;
}
istream &operator>>(istream &stream, Billionaire &o) {
// put your code here
...
return stream;
}
In case you have defined these operators in the Billionaire, the compiler wont be able to use them here : in main you invoke the free standing operator (that you have declared as friend), whereas you would have defined class members that have to be invoked on a Billionaire with the . or -> operator and have a different signature than what you’re using in main.

Related

I'm newbie in c++, got unexpected error while <<operator Overloading. Could you tell me some advise?

While doing some code practice myself I got some Error
student.h file
#pragma once
class Student {
public:
Student() = default;
Student(int id, const char* name, int score);
Student(const Student& s);
Student(Student&& other);
Student& operator=(Student&& other);
virtual ~Student();
**friend std::ostream & operator<<(std::ostream & os, const Student & rhs);**
void print();
private:
int mId;
char* mName;
int mScore;
size_t mSize;
};
student.cpp file
#include "student.h"
#include <iostream>
#include <string>
... //bunch of constructors, override...
std::ostream & operator<<(std::ostream& os, const Student & rhs)
{
os << rhs.mId << rhs.mName << rhs.mScore ; // Compile Error: Cannot Access Student Member(rhs.mId, rhs.mName...)
return os;
}
The Error i got was i cannot access Student class member despite I declared it friend function in student.h
Strange to me, It compiled successfully if i declare #include<iostream> statement in student.cpp file like this
#include <iostream> //change position <iostream> and "student.h"
#include <string>
#include "student.h"
... //bunch of constructors, override...
std::ostream & operator<<(std::ostream& os, const Student & rhs)
{
os << rhs.mId << rhs.mName << rhs.mScore ; //Compile successfully
return os;
}
So, why #include statement sequences are matters? i thought #include statement just copy-paste to my cpp file.
And it also compiled successfully when i declare #include<iostream> to student.h,
so when i include some #include things the Best-case is declare it to header-file?
Could you give me some advise?
I compiled my program in Visual Studio 2019.
In student.h add an include for iosfwd:
#pragma once
#include <iosfwd>
class Student ...
This will ensure correct resolution of the std::ostream symbol and recognize the ostream operator you defined as the one you declared as a friend.
The iosfwd header contains forward declarations of the symbols in iostream header, and it is defined for exactly this scenario.
In C++ we must declare anything before using it.
So your problem is that you haven't declared std::ostream but you have used it in student.h.
An suitable solution is to #include <iostream> in the beginning of student.h, below #pragma once.
You can also put these before class Stduent:
namespace std
{
class ostream;
}
This is called forward declaration.

trouble overloading << operator, trouble printing vectors of objects

Header file:
#ifndef CART_H
#define CART_H
#include "Tops.h"
#include <iostream>
#include <vector>
using namespace std;
class Cart
{
public:
Cart();
void addTop(Tops& top);
friend ostream& operator<<(ostream& ostr, const Cart& c);
private:
vector<Tops> tops;
};
#endif
Implementation file:
#include "Cart.h"
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
Cart::Cart() { }
void Cart::addTop(Tops &top)
{
tops.push_back(top);
}
ostream& operator<<(ostream &ostr, const Cart &c)
{
ostr << "TOPS IN CART:\n-------------\n";
for (auto const top : c.tops) {ostr << top << endl; } // no match for 'operator<<'
return ostr;
}
Problem: I keep getting a "no match for operator<<" error and I have no idea why, and I also have no idea what it means. When I google this error, what has caused the error in other people's codes does not apply to mine.
In your declaration you have stated that the Cart argument will be const:
friend ostream& operator<<(ostream& ostr, const Cart& cart);
but your definition does not:
ostream& operator<<(ostream &ostr, Cart &c)
They need to match (either both const or both not - both const would be right here) for the friend declaration to be of any use.

Implement a non-member, overloaded operator, in a namespace, with correct syntax

Disclaimer: I'm new to programming in c++, I've read through dozens of forums, and can't find an answer to my specific question.
I've included the header and definition files for a Point class below and a main function that calls an overloaded ostream to print the Point. I can't find the correct syntax for the definition for the non member overloaded operator<<. If I have it the way it's posted, I get error message:
undefined reference to `Clustering::operator<<(std::ostream&, Clustering::Point const&)
If I add Clustering:: before the operator<< I get error message:
std::ostream& Clustering::operator<<(std::ostream&, const Clustering::Point&)' should have been declared inside 'Clustering'
std::ostream &Clustering::operator<<(std::ostream &os, const ::Clustering::Point &point)
How is this code supposed to be written?
Point.h file:
#ifndef CLUSTERING_POINT_H
#define CLUSTERING_POINT_H
#include <iostream>
namespace Clustering {
class Point {
int m_dim; // number of dimensions of the point
double *m_values; // values of the point's dimensions
public:
Point(int);
friend std::ostream &operator<<(std::ostream &, const Point &);
};
}
#endif //CLUSTERING_POINT_H
Point.cpp file:
#include "Point.h"
//Constructor
Clustering::Point::Point(int i)
{
m_dim = i;
m_values[i] = {0};
}
std::ostream &operator<<(std::ostream &os, const Clustering::Point &point) {
os << "Test print";
return os;
}
Main.cpp:
#include <iostream>
#include "Point.h"
using namespace std;
using namespace Clustering;`
int main() {
Point p1(5);
cout << p1;
return 0;
}
You need to put your std::ostream &operator<< in Clustering namespace in Point.cpp
namespace Clustering {
std::ostream &operator<<(std::ostream &os, const Clustering::Point &point)
{
// ...
}
}

Error overloading >> Operator reading from file into class

I am currently working on a program for class that requires me to overload the stream extraction operator, >>, to take data from a file straight into a class. I am getting a:
error C2678: binary '>>' : no operator found which takes a left-hand operand of type 'std::ifstream' (or there is no acceptable conversion)
Here is the specific code the error is affecting.
int main()
#include <iostream>
#include <fstream>
#include <iomanip>
#include "stockType.h"
#include "stockListType.h"
using namespace std;
stockType myStock;
stockListType stockList;
ifstream infile;
infile.open("StockData.txt");
infile >> myStock;
stockType.h Header File
#ifndef STOCKTYPE_H
#define STOCKTYPE_H
#include <string>
#include <fstream>
#include <iostream>
class stockType
{
public:
stockType();
void printStock();
void calcPercent();
char Symbol[3];
float openingPrice;
float closingPrice;
float todayHigh;
float todayLow;
float prevClose;
int volume;
float percent;
friend std::ifstream &operator >> (std::ifstream &in, const stockType &myStock);
};
#endif
stockType.cpp Resource File
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "stockType.h"
std::ifstream& operator>> (std::ifstream &in, const stockType &myStock)
{
in >> myStock.Symbol;
in >> myStock.openingPrice;
in >> myStock.closingPrice;
in >> myStock.todayHigh;
in >> myStock.todayLow;
in >> myStock.prevClose;
in >> myStock.volume;
return in;
}
most of the searching I have done is people having problems using ostream to do this and are getting their data during program use. Trying to erorr-correct using the ifstream and reading straight from a txt file has been difficult. I can provide whatever additional information is needed. Any help is much appreciated. thanks.
Your input operator signature
std::ifstream& operator>> (std::ifstream &in, const stockType &myStock);
// ^^^^^
makes no sense. To input anything from the stream to the myStock parameter, it has to be non const of course. Also you usually don't want to overload specific implementations of std::istream, thus your signature should look like this:
std::istream& operator>> (std::istream &in, stockType &myStock);

Friend function across multiple files

Hello I'm in the process of learning about operator overloading and friend functions.
I've declared the operator<< function as a friend of my class in a .h file but I still cant access the private member variables from the function definition in a .cpp file
My code is as follows:
Test.h
class Test
{
private:
int size;
public:
friend ostream& operator<< (ostream &out, Test& test);
};
Test.cpp
#include "Test.h"
#include <iostream>
using namespace std;
ostream& operator<< (ostream& out, Test& test)
{
out << test.size; //member size is inaccessible!
}
Apparently size is inaccessible although I've already made the operator<< function a friend of my class. I've Googled a bit and haven't found anything so can anyone help me out? Thanks.
Note: If I move the class definition to the .cpp file everyone works so I assume my problem has something to do with multiple files.
In c++ the scope of the declaration go from top to bottom. So if you include first Test.h and after that <iostream> the friend declaration has does not know about the type std::ostream.
The solution:
Test.h:
#include <iostream>
class Test
{
private:
int size;
public:
friend std::ostream& operator<< (std::ostream &out,const Test& test);
};
Test.cpp:
#include "Test.h"
std::ostream& operator<< (std::ostream& out,const Test& test)
{
out << test.size;
return (*out);
}
Note that the #include <iostream> has been moved from Test.cpp to Test.h and the argument of the global operator << takes const Test& test. The const makes the operator work for rvalues.