How do I overload the I/O operators C++ - c++

I have created a class that allows the user to input their mailing address, order date, type of cookie ordered and the quantity. There were other errors, but I stayed late and with the assistance of my prof, I have fixed them. Now all that is left is that I need to be able to change code to overload the I/O stream operators so that the objects may be used in standard input and output statements.
I'm not sure what all part of the code everyone will need to see, but I'm going to post the parts I believe are needed for what I'm trying to do.
I need to have it where in the output(), I have cout << order << endl; I will look over the net and will hopefully have it ready by tonight. Thanks for everyone's input.
Was instructed to take down my code due to other students from class copying my code pieces to do their work (knew it was possible but didn't think about it)
However, my code is complete.

Implement two functions:
basic_ostream & operator<< (basic_ostream& ostr, const CookieOrder& co)
basic_istream & operator>> (basic_istream& istr, CookieOrder& co)
the operator<<= function will be called when you use cout << order << endl; and the operator>> function will be called when you use the >> (stream extraction) operator. Be very careful how you implement the stream extraction operator.
You may want to declare either of these as friend to the CookieOrder, as that will allow the function to access the private parts of the class as if the function is a member of the class.
edit to respond to changes in the question
delcare your class as before:
class CookieOrder {
public:
// public methods as before
private:
// private parts as before
};
basic_ostream & operator<< (basic_ostream& ostr, const CookieOrder& co);
basic_istream & operator>> (basic_istream& istr, CookieOrder& co);
Implement the two functions using only the public interface of the CookieOrder class.
For example:
basic_ostream & operator<< (basic_ostream& ostr, const CookieOrder& co)
{
ostr << co.get_customerName() << endl;
/* the rest of the output */
}
These functions are not members of the CookieOrder class, they are normal functions with no special access to the CookieOrder class or instanaces of the class.

As far as comparison is concerned, you'd be better off comparing all upper or all lower (rather than each word's first letter upper), it's simpler to set things that way.
Moreover you should get into the habit of putting braces around code
Why do you have a magic number of 6 in your loop? Especially when you only have five (5) elements.
Perhaps the loop should be
...
int loop_size = sizeof(flavors)/sizeof(flavors[0]);
for (int i = 0; i < loop_size; ++i)
{
if (flavors[i] == cookieOrdered)
{
valid_option = true;
break;
}
}

Hint: lookup Case insensitive string comparison in C++

Related

How to override standard global function in c++ when called on a class just like in defining __str__ in python

Main question:
In python, we can define things like __unicode__ or __str__ in a class, that way when we call print() or str() on a class (i.e. str(myclass)), we get a customized and readable string representation. In C++, how can this be done for a class? Such that when we call string(myclass) we get a string representation of myclass?
Backstory:
This will probably be tagged as a low quality question, as I am very new to C++.
I'm currently working through the C++ exercises in exercism.io, where the point is to write code to enable the provided test cases to pass. I have already finished 30 of the 39 available exercises, however I am currently stuck on this particular test case code:
const auto actual = string(date_independent::clock::at(t.hour, t.minute));
In the previous exercises, I understood this as "create a namespace named date_independent, have a class in it with the name clock, and make the class have a public function named at, that will accept two parameters(in this case 2 integers hour and minute)". I made the function a static function because the test code does not really instantiate a clock object. I also made the return value to be of type std::string. It worked well for the first few test cases. Unfortunately, I then encountered this test code:
const auto actual = string(date_independent::clock::at(a.hour, a.minute).plus(a.add));
In this instance, my previous solution of returning a string backfired since now I need to call a plus() function on the return value of at(). This obviously cannot be done since at() returns a std::string, and strings don't have member functions. This was then I noticed that there's a string() function (?) encapsulating the entire date_independent::clock::at(a.hour, a.minute).plus(a.add). I'm not sure however where this string() function is coming from, and how I could find out. For python, I would assume that this is some sort of type casting into string, or some other function named string. However, this is C++, and I haven't encountered typecasting done like this yet, so maybe it isn't that. My other idea is that, similar to python, maybe classes can override how standard global functions work with them. Like say when __unicode__ or __str__ is defined in a python class so that print statements can return customized values.
So my question once again is, is my assumption that this string function is supposed to be a member function that is meant to be overridden correct? And if it is, how can it be done in C++? I would appreciate any responses. I'm fairly certain that I'm not seeing something fundamental, since I'm new to the language.
Some of the context of the test code is found below.
...
BOOST_AUTO_TEST_CASE(time_tests)
{
for (timeTest t : timeCases) {
const auto actual = string(date_independent::clock::at(t.hour, t.minute));
BOOST_REQUIRE_MESSAGE(t.expected == actual, errorMsg(t.expected, actual, t.msg));
}
}
...
BOOST_AUTO_TEST_CASE(add_tests)
{
for (addTest a : addCases) {
const auto actual = string(date_independent::clock::at(a.hour, a.minute).plus(a.add));
BOOST_REQUIRE_MESSAGE(a.expected == actual, errorMsg(a.expected, actual, a.msg));
}
}
...
If want to output your class in console or write it to a file, you have to override the << operator for your class.
std::ostream& operator<<(std::ostream& os, const person& person)
{
return os << person.first_name << " " << person.last_name;
}
If you just want a std::string, just add a to_string method that returns the string reprentation of your class.
class person
{
public:
std::string to_string() const
{
return first_name + " " + last_name;
}
private:
std::string first_name;
std::string last_name;
};

Using extraction operator to extract data from a complex class hierarchy

1 - Does it sound like a correct approach to use extraction operators to extract some data not from a file but from a big and complex class hierarchy ?
class ComplexInterface
{
//...
};
struct EXTRACTED_DATA
{
//...
friend ComplexInterface& operator>>(const ComplexInterface& interface, EXTRACTED_DATA& extracted)
{
extracted.m_member = interface.someAccessor().getData();
}
};
Would it be better to simply make it a member method (void extractFromComplexInterface(const ComplxInterface&)) ?
Is there a better solution ?
2 - Would it be possible to handle this extraction as a regular stream operation ? The ComplexInterface would become an istream, implementing some magic function in which it would say "I will send this data, then this and that...". Then, the EXTRACTED_DATA could use its regular extraction operator (friend istream& operator>>(istream&, EXTRACTED_DATA&)) which is already defined to read from a file stream.
If this is possible, how ?

How to check data type in C++?

I'm fairly new to C++, I've been mainly using python. I'm trying to check the type of variable of the value stored in the objects I'm working on. I remember that in Python there was a comand isinstance where I could use it as a condition to run certain commands, like if the next value is a string, do A, and if it's an int do B.
Is there a way to quickly check what's the data type on a variable in C++?
Example:
In python I had an array with a math operation, each character in a field
[3,"+",2]
as I read the array I would separate the ints from the strings with the isinstance command
if isinstance(list[0],int):
aux1.append(list[0])
list=list[1:]
else:
if isinstance(lista[0],str):
aux2.append(list[0
list=list[1:]
now in C++ I need to do something similar, but this time each character is in a node from a linked list and again, I need to separate them, ints in a linked list, and strings in another linked list
What you seem to be struggling with is that C++ is a statically and a (relatively) strongly typed language. For a discussion about what each of these terms actually mean i refer to this other question, as it's explained there probably much better than I could.
First of all you should be sure that you actually need to do things the way you're trying currently. Do not try to write Python style code.
That said, there are basically two different approaches with which you can achieve a behavior that's similar to what Python (dynamically typed, duck typing and thus relatively weak typing) allows you to do:
Use C++'s builtin dynamic type mechanisms. Therefore, you need to create a so called polymorphic base class, that is a class that has at least one virtual member function (the destructor also works if you don't have a defined interface - it most often also must be virtual to avoid nasty issues). A short example:
struct Value {
virtual void write_to(std::ostream &) const = 0;
virtual void read_from(std::istream &) = 0;
virtual ~Value() {} // Absolutely required!!!
};
struct Number : public Value {
int data;
void write_to(std::ostream & stream) const {
stream << "<Number " << data << ">";
}
void read_from(std::istream & stream) {
stream >> data; // Not the same format as write_to, shame on me
}
// Implicit destructor is fine
};
struct String : public Value {
std::string data;
void write_to(std::ostream & stream) const {
stream << "<String " << data.size() << " " << data << ">";
}
void read_from(std::istream & stream) {
stream >> data; // Not the same format as write_to, shame on me
}
};
Using this you can now for example store Values whose actual type you can let the user decide:
std::vector<std::unique_ptr<Value>> values;
while (wantsToEnterMoreValues) {
std::string choice = ask("What type of value do you want to enter?");
std::unique_ptr<Value> value;
if (choice == "string") {
value = std::make_unique<String>();
} else if (choice == "number") {
value = std::make_unique<Number>();
} else {
// launch apocalypse
}
value->read_from(std::cin);
values.push_back(value);
}
This is easily extensible to more types. Note that in order to use C++'s builtin dynamic typing you need to go without value semantics, but instead completely use reference semantics, either using real references, or (in most cases where ownership must be transferred, like in above example to the values vector) using pointers.
The dynamic_cast approach works very similar to this, except that you're using runtime type information more explicitly and don't need a unified interface (but have much more work in order to maintain your code).
Use the union language feature. This only has become really possible with C++11, where union members may be non-trivially construable:
enum class Type {
Number, String
};
struct Value {
Type type;
union {
std::string string;
int number;
};
Value(std::string const & s) : type(Type::String), string(s) {}
Value(int n) : type(Type::Number), number(n) {}
Value(Value const & v) : type(v.type) {
switch (type) {
case Type::Number: number = v.number; break;
case Type::String: new (&string) std::string(v.string); break;
default: break; // Launch nuclear missiles
}
}
~Value() {
switch (type) {
case Type::String: string.~std::string(); break;
default: break;
}
}
};
As you can see, this quite a lot of work. With this approach you can use value semantics, but cannot as easily extend your Values to support more types. Moreover, due to using a union, you're going to waste some memory.
Bottom line: You need to implement the behavior on your own, but can do so in exactly the way you want it to behave. For example: You could also implement assignment operators operator=(Value const &) that do implicit type conversions. You can also use the implementations from boost, like boost::any or boost::variant.
I'd like to reference two answers I've written on this site to the very same subject, perhaps they're also helpful for you:
https://stackoverflow.com/a/32926607/1116364
https://stackoverflow.com/a/32041381/1116364
Also some C code which is relevant, because it tries to solve the same issue: https://stackoverflow.com/a/35443434/1116364
Note: All code in this answer is written straight out of memory and not tested. It thus serves only as demonstration of the basic techniques.
Unlike Python, C++ is a strongly typed language. This means that the type of each object is known at compile time.
Having said that, there is a very, very vague analogue that can apply in some circumstances.
If you have a pointer to an object whose class has at least one virtual method, a dynamic_cast will either convert it to a pointer to the requested class, or to a nullptr. This would only work when the most-derived object that's being pointed to includes both classes in its hierarchy, unambiguously.

Conditional output

I'd like to create a C++ ostream object that only outputs anything if a condition holds true, to use for debugging. What would be the easiest way to do this? I know that boost has classes that make this easy, but I'd like to know if there's a simple way to do it without boost. The documentation makes it seem like subclassing ostream::sentry would make this possible, but I can't find any source saying that's something that you can/should do.
Don't subclass, it's easier to use a wrapper:
class MaybeOstream
{
public:
MaybeOstream(std::ostream& stream_) : stream(stream_), bOutput(true) {}
void enable(bool bEnable) { bOutput = bEnable; }
template<typename T>
MaybeOstream& operator<< (T x)
{
if(bOutput)
stream << x;
return *this;
}
// Add other wrappers around ostream: operator void*, good(), fail(),
// eof(), etc., which just call through to the ostream
private:
std::ostream& stream;
bool bOutput;
}
Take a look at this paper on filtered streambufs.

Using a virtually inherited function non-virtually?

I have run into trouble trying to implement functionality for serializing some classes in my game. I store some data in a raw text file and I want to be able to save and load to/from it.
The details of this, however, are irrelevant. The problem is that I am trying to make each object that is interesting for the save file to be able to serialize itself. For this I have defined an interface ISerializable, with purely virtual declarations of operator<< and operator>>.
The class Hierarchy looks something like this
-> GameObject -> Character -> Player ...
ISerializable -> Item -> Container ...
-> Room ...
This means there are many possible situations for serializing the objects of the different classes. Containers, for instance, should call operator<< on all contained items.
Now, since operator>> is virtual, i figured if I wanted to serialize something that implements the functionality defined in ISerializable i could just do something like
ostream & Player::operator<<(ostream & os){
Character::operator<<(os);
os << player_specific_property 1 << " "
<< player_specific_property 2 << "...";
return os;
}
and then
ostream & Character::operator<<(ostream & os){
GameObject::operator<<(os);
os << character_specific_property 1 << " "
<< character_specific_property 2 << "...";
return os;
}
but I quickly learnt that this first attempt was illegal. What I'm asking here is how do I work around this?
I don't feel like implementing a function manually for each class. I guess I'm looking for something like the super functionality from Java.
Any help is appreciated.
-- COMMENTS ON EDIT ------------
Alright, last time I was in a hurry when I was writing the question. The code is now more like it was when I tried to compile it. I fixed the question and the problem I had was unrelated to the question asked. I'm ashamed to say it was caused by an error in the wake of a large refactoring of the code, and the fact that the operator was not implemented in every base class.
Many thanks for the replies however!
The problem is not in your attempt to call a virtual function non-virtually. The problem is this line: os = Character::operator<<(os);. That is an assignment, but std::ostream doesn't have an operator=.
You don't need the assignment anyway. The stream returned is the same stream as the stream you pass in. The only reason it's returned is so you can chain them.
Hence the fix is to just change the code to
ostream & Player::operator<<(ostream & os){
Character::operator<<(os);
os << player_specific_property 1 << " "
<< player_specific_property 2 << "...";
return os;
}
This is not how overloading operator<< for ostream works. The left-hand operator is an ostream (hence you gotta overload it as a free function) and the right-hand operator is your object (which is why the virtual mechanism wouldn't easily work.
I suppose you could try:
class Base
{
//...
virtual std::ostream& output(std::ostream&) const;
};
std::ostream& operator<< (std::ostream& os, const Base& obj)
{
return obj.output(os);
}
Now a derived class naturally might call the output method of its parent(s):
class Derived: public Base
//...
virtual std::ostream& output(std::ostream& os) const
{
Base::output(os);
return os << my_specific_data;
}
};