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;
}
Related
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;
}
};
So I'm defining a variation on int as a rotating integer class which is very simple, but I want to be able to do something like
cout << x << '\n';
rather than :
cout << x.value() << '\n';
Is this at all possible?
Is there nothing like
class rotating_int
{
private:
int _value, _low, _high;
public:
int operator++(int) { if (++_value > _high) _value = _low; return _value; }
int operator--(int) { if (--_value < _low) _value = _high; return _value; }
int operator++() { if (++_value > _high) _value = _low; return _value; }
int operator--() { if (--_value < _low) _value = _high; return _value; }
void operator=(int value) { _value = value; }
int operator==(int value) { return _value == value; }
int val() { return _value; }
rotating_int(int value, int low, int high) { _value = value; _low = low; _high = high; }
int ^rotating_array() { return &_value; }
};
Where "^rotating_array" is much like the definition of a destructor ~rotating_array.
Seem to be a fundamental of object orientated design that it should be.
You should use operator overloading.
Inside your class:
friend ostream& operator<<(ostream& os, const RotatingInt& x)
{
os << x.value;
return os;
}
Change RotatingInt to your class name.
Here's an example: http://cpp.sh/9turd
To do this, C++ has something extremely useful but it takes some effort to really understand it. As Borgleader indicates: you want to overload the << operator.
In your rotating integer class you need to tell the compiler that the operator<< (this is how the function is called which the compiler calls when it sees the << operator for any object) can access the private members of the class. This is done by making the function a friend function of the rotating integer class. In the class you add:
friend std::ostream& operator<<(std::ostream&, const RotatingInteger&)
The implementation of the operator<< function could look like this:
std::ostream& operator<<(std::ostream& os, const RotatingInteger& i) {
os << i.value;
return os; // you need to return the stream in order to add something
// else after you pass the RotatigInteger-object like in your
// example: cout << x << "\n";
}
I am trying to use boost::lexical_cast to convert my user defined type into an integer.
However, I get an exception. What am I missing??
class Employee {
private:
string name;
int empID;
public:
Employee() : name(""), empID(-1)
{ }
friend ostream& operator << (ostream& os, const Employee& e) {
os << e.empID << endl;
return os;
}
/*
operator int() {
return empID;
}*/
};
int main() {
Employee e1("Rajat", 148);
int eIDInteger = boost::lexical_cast<int>(e1); // I am expecting 148 here.
return 0;
}
I know I can always use the conversion operator, but just wondering why lexical cast doesn't work here.
The problem is that what you insert into the output stream is not the representation of an integer (because of the trailing << std::endl). The following fails in a similar way:
boost::lexical_cast<int>("148\n")
Removing the << std::endl makes it work:
friend std::ostream& operator << (std::ostream& os, const Employee& e) {
os << e.empID;
// ^^^^^^^^^^^^^^
// Without << std::endl;
return os;
}
I am learning C++, and learned that int-types are just premade classes. So I thought maybe i should try to create one.
What I want to do basically is a
normal class of int
int x;
x=7;
cout << x;
// Output is 7 on screen.
so similarly...
abc x;
x=7;
cout << x;
What would I put in
class abc{
\\ HERE!!!!!!
};
so I could do this
class SomeClass {
public:
int x;
SomeClass(int x) {
this->x = x;
}
};
int main(int argc, char *argv[]) {
SomeClass s = 5;
cout << s.x << "\n"; // 5
s = 17;
cout << s.x << "\n"; // 17
return 0;
}
But as you can see I have to use s.x to print the value - I just want to use 's'.
I am doing it as an experiment, I don't want to hear about how this method is good or bad, pointless or revolutionary, or can 't be done. I remember once I did it. But only by copying and pasting code that I didn't fully understand, and have even forgotten about.
and learned that int, types, are just premade classes
This is completely false. Still, you have complete control on how your class will behave in expressions, since you can overload (almost) any operator. What you are missing here is the usual operator<< overload that is invoked when you do:
cout<<s;
You can create it like this:
std::ostream & operator<<(std::ostream & os, const SomeClass & Right)
{
Os<<Right.x;
return Os;
}
For more information, see the FAQ about operator overloading.
the << and >> are basically function names. you need to define them for your class. same with the +, -, * and all the other operators. here is how:
http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html
You need to overload operator<< for your class, like so:
class abc
{
public:
abc(int x) : m_X(x) {}
private:
int m_X;
friend std::ostream& operator<<(std::ostream& stream, const abc& obj);
};
std::ostream& operator<<(std::ostream& os, const abc& obj)
{
return os << obj.m_X;
}
You don't have to friend your operator<< overload unless you want to access protected/private members.
You must define in your class abc cast operator to int and assignment operator from int, like in this template class:
template <class T>
class TypeWrapper {
public:
TypeWrapper(const T& value) : value(value) {}
TypeWrapper() {}
operator T() const { return value; }
TypeWrapper& operator (const T& value) { this->value = value; return *this; }
private:
T value;
};
int main() {
TypeWrapper<int> x;
x = 7;
cout << x << endl;
}
You want to overload the output operator:
std::ostream& operator<< (std::ostream& out, SomeClass const& value) {
// format value appropriately
return out;
}
I'd like to control what is written to a stream, i.e. cout, for an object of a custom class. Is that possible in C++? In Java you could override the toString() method for similar purpose.
In C++ you can overload operator<< for ostream and your custom class:
class A {
public:
int i;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.i << ")";
}
This way you can output instances of your class on streams:
A x = ...;
std::cout << x << std::endl;
In case your operator<< wants to print out internals of class A and really needs access to its private and protected members you could also declare it as a friend function:
class A {
private:
friend std::ostream& operator<<(std::ostream&, const A&);
int j;
};
std::ostream& operator<<(std::ostream &strm, const A &a) {
return strm << "A(" << a.j << ")";
}
You can also do it this way, allowing polymorphism:
class Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Base: " << b << "; ";
}
private:
int b;
};
class Derived : public Base {
public:
virtual std::ostream& dump(std::ostream& o) const {
return o << "Derived: " << d << "; ";
}
private:
int d;
}
std::ostream& operator<<(std::ostream& o, const Base& b) { return b.dump(o); }
In C++11, to_string is finally added to the standard.
http://en.cppreference.com/w/cpp/string/basic_string/to_string
As an extension to what John said, if you want to extract the string representation and store it in a std::string do this:
#include <sstream>
// ...
// Suppose a class A
A a;
std::stringstream sstream;
sstream << a;
std::string s = sstream.str(); // or you could use sstream >> s but that would skip out whitespace
std::stringstream is located in the <sstream> header.
The question has been answered. But I wanted to add a concrete example.
class Point{
public:
Point(int theX, int theY) :x(theX), y(theY)
{}
// Print the object
friend ostream& operator <<(ostream& outputStream, const Point& p);
private:
int x;
int y;
};
ostream& operator <<(ostream& outputStream, const Point& p){
int posX = p.x;
int posY = p.y;
outputStream << "x="<<posX<<","<<"y="<<posY;
return outputStream;
}
This example requires understanding operator overload.