Suppose this is my class:
class Student {
std::string name;
int CWID;
public:
Student(std::string name = "N/A", int CWID = 99999999) : this->name(name), this->CWID(CWID) {}
};
Now, how do I overload the output stream operator << that will print all the data in the class. I'm guessing this is equivalent to the toString() method in Java but kindly show me how to do it in C++.
Add member functions to the class that return the name and CWID.
std::string getName() const {return name;}
int getCWID() const {return CWID;}
Then, add a non-member function to write the data out to a stream.
std::ostream& operator<<(std::ostream& out, Student const& s)
{
return out << s.getName() << " " << s.getCWID();
}
Here is how you do it:
class Student {
std::string name;
int CWID;
public:
Student(std::string name = "N/A", int CWID = 99999999) : name(name), CWID(CWID) {}
friend std::ostream& operator<<(std::ostream& stream, const Student& student);
};
std::ostream& operator<<(std::ostream& stream, const Student& student)
{
stream << '(' << student.name << ", " << student.CWID << ')';
return stream;
}
Please note that this overloaded function is not part of the class.
You could write non-member function
std::ostream& operator<<(std::ostream& os, const Student& stud)
{
os << stud.name << " " << stud.CWID;
return os;
}
and declare it as friend function in your class
class Student {
std::string name;
int CWID;
public:
Student(std::string name = "N/A", int CWID = 99999999) : this->name(name), this->CWID(CWID) {}
friend ostream& operator<<(ostream& os, const Student& stud);
};
Related
I had a class name address:
#ifndef __ADRESS
#define __ADRESS
#include <iostream>
using namespace std;
class Adress
{
private:
std::string street;
int number;
std::string city;
public:
Adress(std::string name = "Hertzel", int number = 1, std::string city = "Tel Aviv"); //C'tor
Adress(const Adress& other); //cpy c'tor
Adress(Adress&& other);//Move c'tor
//Get methods
const string& getStreet() const;
int getNumber() const;
const string& getCity() const;
//Set methods
bool setStreet(std::string streetName);
bool setNumber(int num);
bool setCity(std::string cityName);
const Adress& operator=(const Adress& other);
friend ostream& operator<<(ostream& os, const Adress& adress);
};
#endif // !__ADRESS
The street and city were originally char* and now I changed it to strings.
But now I have a weird issue. While using char* I managed to use operator<< function inorder to print the content of address, now after switching to string instead char* when I try printing an address the program terminates.
This is the implementation I wrote for the function:
ostream& operator<<(ostream& os, const Adress& adress)
{
os << adress.street << " " << adress.number << " " << adress.city;
return os;
}
Is anyone familiar with that problem?
Thanks!
The error appears to be elsewhere. You didn't give any implementation file so I had to fill in a dummy implementation for the setters and I can't reproduce the error.
#ifndef ADDRESS_H
#define ADDRESS_H
#include <ostream>
#include <string>
class Adress{
private:
std::string street;
int number; //can this be negative or zero
std::string city;
public:
~Adress() = default;
Adress() : street("Hertzel"), number(1), city("Tel Aviv"){}
Adress(const Adress& other) = default;
Adress(Adress&& other) = default;
Adress& operator=(const Adress& other) = default;
//Get methods
const std::string& getStreet() const { return street; }
int getNumber() const { return number; }
const std::string& getCity() const{ return city; }
//Set methods
bool setStreet(std::string streetName) {
//check empty, is_alphanum etc
street = streetName;
return true;
}
bool setNumber(int num){
//check zero negative
number = num;
return true;
}
bool setCity(std::string cityName){
//checks here
city = cityName;
return true;
}
friend std::ostream& operator << (std::ostream& os, const Adress& adress);
};
inline std::ostream& operator << (std::ostream& os, const Adress& adress){
os << adress.street << " " << adress.number << " " << adress.city;
return os;
}
#endif
main
#include <iostream>
#include "address.hpp"
int main(int, char**){
Adress a;
std::cout << a << '\n';
}
Compiled with gcc-10 seems fine. Debugger time it appears
Imagine a setup as follows. How do I invoke the base class cout from within the derived class cout? I could use the getBrand() method, but I feel like I should be able to directly access the base class' cout friend function.
I hacked a bit, and tried this.Brand and also just Brand. No luck.
class Brand {
public:
Brand(std::string brand):brand_(brand) {};
friend std::ostream & operator << (std::ostream & out, const Brand & b) {
out << b.brand_ << ' ';
return out;
}
std::string getBrand()const { return brand_; }
private:
std::string brand_;
}
class Cheese : public Brand {
public:
Cheese(std::string brand, std::string type):Brand(brand), type_(type) {};
friend std::ostream & operator << (std::ostream & out, const Cheese & c) {
out << /* THIS.BRAND?! BRAND?! getBrand() meh.. */ << ' ' << c.type_ << std::endl; // <-- HERE
return out;
}
private:
std::string type_;
}
int main() {
Cheese c("Cabot Clothbound", "Cheddar");
std::cout << c << std::endl;
}
DESIRED OUTPUT
Cabot Clothbound Cheddar
You could invoke the overloaded operator << of the Base class from the derived class. Since, you declared the operator as a friend, you could simply cast the the derived class to a base class:
class Cheese : public Brand {
public:
Cheese(std::string brand, std::string type):Brand(brand), type_(type) {};
friend std::ostream & operator << (std::ostream & out, const Cheese & c) {
//ADDED
out << static_cast<const Brand&>(c) << c.type_ << std::endl;
return out;
}
private:
std::string type_;
};
Output:
Cabot Clothbound Cheddar
See it Live
Cast it, like this:
friend std::ostream& operator<<(std::ostream& out, const Cheese& c)
{
out << static_cast<const Brand &>(c);
out << c.type_ << std::endl;
return out;
}
All other answers are responding correctly to your specific question, but whenever you'll try to use polymorphism like this:
Brand const &c = Cheese("Cabot Clothbound", "Cheddar");
std::cout << c << std::endl;
operator << corresponding to Brand will be called instead of Cheese's.
The good way to do it is to use a virtual print member function:
class Brand {
public:
Brand(std::string const & brand):brand_(brand) {}
virtual ~Brand() {}
virtual void print(std::ostream & out) const {
out << brand_;
}
std::string const & getBrand()const { return brand_; }
private:
std::string brand_;
};
class Cheese : public Brand {
public:
Cheese(std::string const & brand, std::string const & type):Brand(brand), type_(type) {}
void print(std::ostream & out) const override {
Brand::print(out); // calling base print()
out << ' ' << type_ << std::endl;
}
private:
std::string type_;
};
Then, you only need a single operator << for the base class which will call your print virtual member function:
std::ostream & operator << (std::ostream & out, const Brand & b) {
b.print(out);
return out;
}
DEMO
You obviously can't do anything like Brand::operator<<, because both operator<< are defined as friend and thus they are not member functions.
If you want to invoke operator<<(std::ostream&, const Brand&), you just have to pass correct types to that, and since Derived classes can be easily casted to Base classes, you can just do
friend std::ostream & operator << (std::ostream & out, const Cheese & c) {
out << static_cast<const Brand&>(c) << ' ' << c.type_ << std::endl;
return out;
}
I have two class:
The parent class: Vehicle
class Vehicle {
private:
string manufacturer;
int cylinder;
Person owner;
public:
Vehicle();
Vehicle(const Vehicle& theObject);
friend istream& operator >>(istream& inStream, Vehicle& object);
friend ostream& operator <<(ostream& outStream, const Vehicle& object);
};
and the child class: Truck
I overload operator<< and operator>> so that I can use cout and cin with my class Truck. Here is my definition with these two operators:
class Truck : public Vehicle {
private:
double loadCapacity;
int towingCapacity;
public:
Truck();
Truck(const Truck& object);
friend istream& operator >>(istream& inStream, Truck& object);
friend ostream& operator <<(ostream& outStream, const Truck& object);
};
istream& operator >>(istream& inStream, Truck& object) {
cout << endl << "Insert truck: "; inStream >> object;
cout << "Insert load capacity: "; inStream >> object.loadCapacity;
cout << "Insert towing capacity: "; inStream >> object.towingCapacity;
return inStream;
}
ostream& operator <<(ostream& outStream, const Truck& object) {
outStream << object;
outStream << endl << "Load capacity: " << object.loadCapacity;
outStream << endl << "Towing capacity: " << object.towingCapacity;
return outStream;
}
When I try to use
Truck object;
cin >> object;
cout << object
It does not work out as I think. Can anybody explain why?
Thank you
inStream >> object and outStream << object are both recursive calls because the static type of object is Truck, not Vehicle. Use a virtual print and get method that Truck overrides. Call object.print(outStream) in the inserter and object.get(inStream) in the extractor in order to achieve polymorphic I/O through inheritance:
class Vehicle {
private:
string manufacturer;
int cylinder;
Person owner;
public:
Vehicle();
Vehicle(const Vehicle& theObject);
virtual void print(std::ostream& os) const {
os << manufacturer << cylinder << owner;
}
virtual void get(std::istream& is) {
is >> manufacturer >> cylinder >> owner;
}
};
class Truck : public Vehicle {
private:
double loadCapacity;
int towingCapacity;
public:
Truck();
Truck(const Truck& object);
void print(std::ostream& os) const {
Vehicle::print(os);
os << loadCapacity << towingCapacity;
}
void get(std::istream& is) {
Vehicle::get(is);
is >> loadCapacity >> towingCapacity;
}
};
std::istream& operator>>(std::istream& inStream, Vehicle& object) {
object.get(inStream);
return inStream;
}
std::ostream& operator<<(std::ostream& outStream, const Vehicle& object) {
object.print(outStream);
return outStream;
}
I'm writing a basic overload of the << operator so I've added a friend function inside the class interface
namespace Warehouse
{
namespace Dto
{
class Product;
class AbstractOrder : public ICloneableItem
{
protected:
unsigned long _id;
std::string _name;
std::vector<Product*> _products;
public:
AbstractOrder();
virtual ~AbstractOrder();
double computePrice() const;
void addProduct(Product* product);
void removeProduct(Product* product);
void removeAllProducts();
void setName(const std::string& name) { _name = name; }
std::string getName() const { return _name; }
unsigned long getId() const { return _id; }
std::vector<Product*> getProductList() const { return _products; }
friend std::ostream& operator<<(std::ostream& os, const AbstractOrder& ord);
};
}
}
Inside the implementation file this is the code of the function
using namespace Warehouse::Dto;
....
std::ostream& operator<<(std::ostream& os, const AbstractOrder& ord)
{
os << "[" << ord._id << "] Order " << ord._name << ": " << ord.computePrice();
return os;
}
Why I'm getting the following error?
Error 1 error C2248: 'Warehouse::Dto::AbstractOrder::_id' : cannot access protected member declared in class 'Warehouse::Dto::AbstractOrder'
Actually I've already fixed it,prepending the namespace before the operator<< on the implementation file.
What I don't understand is why I have to do it even if in the implementation file I've used a using namespace Warehouse::Dto directive?
Because the operator << is defined in the global namespace and the AbstractOrder class is defined in the Warehouse::Dto namespace. But the friend declaration is for a stream operator in the Warehouse::Dto namespace.
If you want to defined proper friend declaration for the operator in the global namespace is would be:
friend std::ostream& ::operator<<(std::ostream& os, const AbstractOrder& ord);
But then again you want the operator to live in the same namespace as the class it is streaming.
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.