Operator overloading with files - c++

Is there a way in which I can use a operator overloader to output to a file. I understand the code behind the actual outputting to a file but I don't understand how I would actually invoke a overloader to carry out the out to the file
Any help in helping me understand this would be appreciated

struct A {
int a;
public:
std::ostream& save(std::ostream& out) const {
return out << a;
}
std::istream& load(std::istream& in) {
return in >> a;
}
};
std::ostream& operator<<(std::ostream& out, const A& obj) {
return obj.save(out);
}
std::istream& operator>>(std::istream& in, A& obj) {
return obj.load(in);
}
int main() {
A a;
std::cin >> a;
std::cout << a;
return 0;
}

Related

c++ operator overloading code have no data ouput

class mod5
{
private:
unsigned i;
public:
mod5() :
i{}
{
}
mod5(mod5 const&) = default;
mod5& operator=(mod5 const&) = default;
explicit mod5(unsigned value) :
i{value}
{
}
unsigned mod_value() const
{
return i % 5;
}
friend auto operator<=>(mod5 const& lhs, mod5 const& rhs)
{
return lhs.mod_value() <=> rhs.mod_value();
}
};
std::istream& operator>>(std::istream& is, mod5& m)
{
unsigned int temp;
if(is >> temp ){
m = mod5(temp);
}
else{
is.setstate(std::ios_base::failbit);
}
return is;
}
std::ostream& operator<<(std::ostream& os, mod5 const& m)
{
os << m.mod_value();
return os;
}
//=============================================================================
The code has been compiled successfully, but there will be no data when the file is added and run. I want to know which step is wrong?
The result of running is as shown below。
rel_demo: operator==(): rel_demo: operator<(): rel_demo: operator>(): stack(0):
The data does not seem to be well imported resulting in no data flow output.
The problem lies in the function of std::ostream& operator<<? Or is it on the function of std::istream& operator>>?

No operator "<<" matches these operands error between an object and a string literal

The code:
catch (test& t)
{
cout << t /*error here*/<</*to here*/ " is not a positive number";
}
causes an error:
No operator "<<" matches these operands
The compiler (c++ 20) says that the error is the << between t and " is not a positive number". It might be caused because I overloaded the operator wrong?
Here's my operator << overload:
ostream& operator << (ostream& os, const test& t)
{
os << t.getX(); //getX is just a method for getting private member
return os;
}
The entire code, if this isn't enough:
class test
{
int x;
public:
explicit test(const int _x)
{
x = _x;
}
int getX() const
{
return x;
}
friend test& operator << (ostream&, test&);
};
ostream& operator << (ostream& os, const test& t)
{
os << t.getX();
return os;
}
auto main() -> int
{
int n;
cin >> n;
try
{
if (n < 0)
{
throw test(n);
}
}
catch (test& t)
{
cout << t /*error here*/ <</*to here*/ " is not a positive number";
}
}
You have declared one operator<<, and defined a different one. And the wrongly-formed one turns out to be the best match.
Replace* this, which you have declared in your class:
test & operator << (ostream & , test & )
With this, which you have defined:
ostream & operator << (ostream & os, const test & t)
Edit:
*An astute observation from the frequently-astute Mark Ransom:
The bad declaration isn't needed at all. The function doesn't need to be declared friend. That declaration could simply be removed.
The friend modifier is required if you declare operator overloading as a class/structure member. In the case of declaring globally, it is not necessary indeed!
First option:
class test {
int x;
public:
explicit test(const int _x) { x = _x; }
int getX() const { return x; }
};
std::ostream& operator<<(std::ostream& os, const test &t) {
os << t.getX();
return os;
}
Second option:
class test {
int x;
public:
explicit test(const int _x) { x = _x; }
int getX() const { return x; }
friend std::ostream& operator<<(std::ostream& os, const test &t) {
os << t.getX();
return os;
}
};

Istream input checking

I have function, which recieves coeffecents of polynomial via istream input. Im struggling with implementing this piece of code into it (can't fully understand how istream& works), so i can shield it from incorrect input. :
while (!std::cin.good())
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "error";
std::cin >> A;
}
Into the function itself:
std::istream& operator>>(std::istream& s, Polynom& c)
{
for (int i = 0; i <= c.degree; i++)
s >> c.coefficents[i];
return s;
}
Needless to say, that's how it is implemented in main()
std::cin >> A;
Polynom class:
class Polynom
{
private:
int degree;
double* coefficents;
public:
Polynom();
Polynom(int size);
Polynom(const Polynom&);
~Polynom();
int get_degree();
double get_coefficents(int);
Polynom operator+(const Polynom&);
Polynom operator-(const Polynom&);
Polynom operator*(double p);
void operator=(const Polynom&);
friend std::ostream& operator<< (std::ostream& s, const Polynom& c);
friend std::istream& operator>> (std::istream& s, Polynom& c);
double& operator()(int i)
{
return coefficents[i];
}
};
Any hints or optimal solutions are welcomed :)
Expanding my comment to an answer, it's possible to make a function which takes the stream and uses the read-validation loop inside it to get the value.
Then in your operator>> overload you call this function to get each value.
Perhaps something like this:
template<typename T>
bool get_value(std::istream& input, T& value)
{
while (!(input >> value))
{
// If end of file, don't attempt any more validation
if (input.eof())
{
return false;
}
// Clear the error
input.clear();
// Ignore the rest of the line
input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
// When the loop ends, we have successfully read a value from the stream
// Return true to tell that
return true;
}
You could use it as:
std::istream& operator>>(std::istream& s, Polynom& c)
{
double value;
for (int i = 0; i <= c.degree && get_value(s, value); i++)
c.coefficents[i] = value;
return s;
}

how to write operator overloading for operator [] in c++

I want to make three[0]='p'; work in the code below. I think I have to make an operator overloading for that but I don't know how to do. What I want to get is to change first index of "Lottery winner!" to 'p'. (To get "pottery winner!").
#include<iostream>
#include<cstring>
using namespace std;
class str
{
char* a;
public:
str(char *aa=""){
this->a = new char[strlen(aa)+1];
strcpy(a,aa);
}
~str(){
delete a;
}
friend ostream& operator<<(ostream &out, str &aa);
friend istream& operator>>(istream &in, str &aa);
};
ostream& operator<<(ostream &out, str &aa){
out<<aa.a;
return out;
}
istream& operator>>(istream &in, str &aa){
in>>aa.a;
return in;
}
void main(){
str three("Lottery winner!");
three[0]='p';
cout<<three<<endl;
}
This is the general signature of the operator[]:
T& operator[](any_type);
In your context it would look like this:
struct str {
...
char& operator[](std::size_t pos) {
return a[pos];
}
};
class str
{
// ...
public:
// ...
char& operator[] (int x)
{
// add array out-of-bounds check here if you like to ...
return a[x];
}
}
operator char*()
{
return a;
}
Could also work

Is it possible to get private variable value using class instance name?

For example, I've written a class called Length:
class Length {
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
void print(float value) {
std::cout << value;
}
void computeStuff(float value) {
//do the computing
}
int main() {
Length width;
width.setValue(5);
std::cout << width; // <-- this is actually just an example
//what I actually want is:
print(width); // print 5
//or perhaps even
computeStuff(width);
return 0;
}
Now how to make width return value_ or 5?
Technically, width is not an instance name, it's a name of a variable of type Length. You can change your code to retrieve a variable in two ways:
Add a friend operator << for Length that does the printing, or
Add an implicit conversion operator from Length to float.
The first approach works only for output. You cannot pull the value directly:
friend ostream& operator <<(ostream& out, const Length& len) {
out << len.value_;
return out;
}
The second approach looks like this:
class Length {
...
public:
operator float() const { return value_; }
};
You must overload operator<< for your custom type, something like:
class Length
{
..
friend std::ostream& operator<<(std::ostream& os, const Length& o);
..
}
std::ostream& operator<<(std::ostream& os, const Length& o)
{
os << o.value_;
return os;
}
Mind that this
must be non member
is nothing special , just an operator overload applied to a standard way of inserting things into stream of <iostream>
You need to define an operator() method to print the value 5.
You need to overload the << operator for your class. You could also use a function to do the operator's work.
Operator <<
#include <iostream>
class Length {
friend std::ostream& operator<<(std::ostream& os, const Length& l);
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
std::ostream& operator<<(std::ostream& os, const Length& l)
{
os << l.value_;
return os;
}
int main() {
Length width;
width.setValue(5);
std::cout << width << std::endl; // print 5
return 0;
}
function:
#include <iostream>
class Length {
friend std::ostream& print(std::ostream &,const Length &l);
public:
void setValue(float);
private:
float value_;
};
void
Length::setValue(float newValue) {
value_ = newValue;
}
std::ostream& print(std::ostream &os, const Length &l)
{
os << l.value_;
return os;
}
int main() {
Length width;
width.setValue(5);
print(std::cout, width) << std::endl;
return 0;
}