We know that the fascinating class iostream is something too powerful.
it has overloded the insertion operator "<<" to take many datatypes:
ostream& operator(ostream&, int),
ostream& operator(ostream&, char)...
we cannot instantiaate ostream: ostream print;
because ostream because its most CTORSs are "protected-socoped" (cannot be accessed from outside).
the only Constructor we can call is ostream(streambuf*) which takes a pointer to another class object ( class streambuf);
I just wanted to mess up with this class:
#include <ostream>
using namespace std;
int operator << (ostream& out, int* x)
{
out << "invoked!" << endl;
cout << *x; // works well!
cout << x; // normally works well and it prints the address that x points to but instead the program get in infinite loop or crushes!
return *x;
}
int main()
{
system("color 1f");
int* pVal = new int(57);
cout << *pVal << endl;
int* pX = new int(7);
cout << *pX << endl;
cout << *pVal << ", " << *pX << endl;
//cout << pVal << endl; // this doesn't work because my operator returns
//int and not a reference to ostream.
// and it is equal to: 0 << endl; which generates the same error
cout << pVal; // this works
// cout << endl << endl << endl;
return 0;
}
I overloaded the insertion operator to take an lvalue as a reference to an ostream object and a pointer to int as rvalue, I popup a message inside my function to get sure that it is invoked.
Note that I intentionally overloaded it to return int value so that no one can write:
out << pInt << *pInt << endl;
... but just:
out << pInt;
My problem, as you can see in the inline-comments above, is that whilst cout << x normally works well, instead the program get in infinite loop or crushes!
return *x;
Can anyone explain why I am getting the error?
The problem hapens because if you just cout << x, it will call your overloaded function over and over. It never returns.
Here's the solution (cast x to void*)
int operator << (ostream& out, int* x)
{
out << "invoked!" << endl;
cout << *x; // works well!
cout << (void*)x;
return *x;
}
Related
I'm following simple C++ tutorial.
#include <iostream>
using namespace std;
int main()
{
int a = 1, b = 2;
cout << "Before swapping " << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(a,b);
cout << endl;
cout << "After swapping " << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int &n1, int &n2)
{
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
The above code works fine (both g++ and icc), but if I were to use pointers in the functions the code fails if I do not include the prototype at the head of the program.
#include <iostream>
using namespace std;
void swap(int*, int*); // The code fails if I comment this line.
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << endl;
cout << "After swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
As far as I know, C++ compiling process is top-bottom, so the 2nd code seems more reasonable in which the information of the function is provided before int main() is encountered. My question is, why the 1st code works fine even without the knowledge of function before int main()?
The issue with the first program is you're not actually calling your own swap function. At the top of the file, you have:
using namespace std;
which brings std::swap into scope and that's the function that you're actually calling. If you put a cout statement in your own swap you'll see that it's never actually called. Alternatively, if you declare your swap before main, you'll get an ambiguous call.
Note that this code is not required to behave like this, since iostream doesn't necessarily bring std::swap into scope, in which case you'll get the error that there is no swap to call.
In the second program, the call to swap(&a, &b) fails because there is no overload of std::swap that accepts 2 temporary pointers. If you declare your swap function before the call in main, then it calls your own function.
The real bug in your code is the using namespace std;. Never do that and you'll avoid issues of this nature.
The reason why the first version works is because it doesn't call your swap(...) function at all. The namespace std provides - Edit: depending on the headers you (and the standard headers themselves) include - swap(...) functions for various types and integers are one of them. If you would remove using namespace std you would have to type std::swap(...) to achieve the same effect (same goes for std::cout, std::endl).
That's one reason why using namespace is a double-edged sword for beginners in my opinion but that's another topic.
Your code is fine; but you're right, it fails if you comment on the line you point to.
But actually, as the others tell you, there is a Swap function in c ++, so it doesn't matter if you create a prototype of the function and do it later because the compiler calls its own swap function.
But since swap works for any data type, except for pointers, then you will understand the reason for your problem, since in this case you do have to create your own swap function that accepts pointers as parameters.
Just move your function above main to make it work correctly, nothing more:
#include <iostream>
using namespace std;
//void swap(int*, int*); // The code fails if I comment this line.
void swap(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << endl;
cout << "After swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
I hope this time my question is better formulated and formatted.
Here's the code that produces two separate outputs when I think it should not since I use everytime (I think) the overloaded operator<< for an enum type.
#include <iostream>
using namespace std;
enum Etat { Intact = 5 };
class Ship {
public:
Etat etat_;
Ship ( Etat t = Intact) : etat_(t) {}
~ Ship() {}
ostream& description ( ) const { return cout << "Etat: " << etat_ << " --- ";}
//---------------------------------------ˆˆˆˆ----
};
ostream& operator<< ( ostream& s, const Etat& etat_ )
{
switch ( etat_ )
{
case Intact: s << "intact"; break;
default: s << "unknown state";
}
return s;
}
ostream& operator<< ( ostream& s, Ship n ) { return s << "Etat: " << n.etat_ ; }
int main()
{
Etat etat_ = Intact;
cout << endl << endl << "Etat: "
<< etat_ << " \"cout << etat_\"" << endl << endl;
cout << Ship(etat_)
<< " \"cout << Ship(etat_)\"" << endl << endl;
cout << Ship(etat_).description()
<< " \"cout << Ship(etat_).description()\"" << endl << endl;
return 0;
}
This is what I get in the terminal:
Etat: intact "cout << etat_"
Etat: intact "cout << Ship(etat_)"
Etat: 5 --- 1 "cout << Ship(etat_).description()"
Can anyone explain to me why, in the last case, not only it takes the integer value of the enum attribut, but also adds a "1" after the test string " --- "???
The only thing I can think of is because I used an unorthodox return method in description(), ie 'return cout << ..", but it seems to work since the test string appears.
Is there a way to force the use of the operator<< overload in description()?
Thanks
In the description() function you are returning a reference to std::cout and use it in the std::cout call in main function. There is a reason why operator<< takes an ostream reference as it's first argument. You should modify your function like this and all should work:
ostream& description(ostream& os) const {
return os << "Etat: " << etat_ << " --- ";
}
The random "1" printed out there is caused likely due to the ostream in your example trying to print out reference to itself.
I'm wondering what a call to an object is supposed to display. I have a class called big_number that has a few different constructors. In another method, I'm declaring an object 'a' using class big_number as follows:
big_number a;
cout << "Default constructor gives " << a << endl;
And my constructor is:
big_number::big_number()
{
head_ptr = 0;
tail_ptr = 0;
positive = false;
digits = 0;
base = 10;
}
(Although I'm sure that this constructor is wrong).
The full code of the testing file:
int main()
{
int n1, n2;
unsigned int base;
string s;
char choice;
do
{
cout << "Type 'd' to test default constructor" << endl;
cout << "Type 'i' to test int constructor" << endl;
cout << "Type 's' to test string constructor" << endl;
cout << "Type 'a' to test assignment" << endl;
cout << "Type '>' to test input operator" << endl;
cout << "Type '=' to test comparison operators" << endl;
cout << "Type 'q' to quit" << endl;
cin >> choice;
if (toupper(choice) == 'D')
{
big_number a;
cout << "Default constructor gives " << a << endl;
}
//More Code
If by "call to an object" you mean your call of the operator<< on the object a with cout as the stream argument: It displays whatever you define it to display (in a member function of big_number or a free function). There is no "default" operator<< for user-defined classes. So, if you define it like
#include <iostream>
struct big_number
{
template<typename T>
friend T& operator<< (T& stream, const big_number& bn);
};
template<typename T>
T& operator<<(T& stream, const big_number& bn) {
return (stream << "Hello World");
}
int main()
{
big_number a;
std::cout << a << std::endl;
}
... it will just display "Hello world".
The purpose of making it a friend function is so it can access the private data members of big_number (since you usually want it to display something that depends on the data stored in the object, and not a constant "Hello world"). So, within the operator<< definition, you would probably iterate through the digits in your linked list and push them to the stream (if I understand correctly what you are trying to do).
I was told in this answer to delete the member myValue in the destructor. But if I add it I am getting an exception. From the console messages it seems to be entering the destructor at two moments with the same object(!?)
Note: The code is my attempt to an exercise. In it we are given a code to which we can only add to it. Essentially the content of the main and the constructor without parameters is that is given. The rest is what I am adding to it to make it work.
My guess is that a copy of the object made during some function call is destroying the same myValue after exiting the function call. How is the right way to preserve the data pointed to by two objects in this case?
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class MyFancyInt
{
public:
// A constructor that inputs a value for initialization, so that line /*1*/ makes sense.
MyFancyInt(int x) : myValue(new int(x))// The part after the : initializes myValue to point to the newly created int with value x.
{
cout << "Constructor that initializes with myValue = " << x << endl;
};
//Destructor.
~MyFancyInt()
{
cout << "A MyFancyInt destroyed that had the myValue = "<< this->myValue<< " pointing to a "<< *(this->myValue) << endl;
//delete myValue;
};
//A 'Copy Constructor', so that line /*3*/ makes sense. Aparently C++ creates default copy constructors.
//A copy constructor input an already existing MyFancyInt, creates a new MyFancyInt and initializes it with the data of the former.
MyFancyInt(MyFancyInt& x)
{
myValue = x.myValue;
};
//The construtor without parameters already given in the exercise.
MyFancyInt()
{
cout << "Default constructor" << endl;
myValue = 0;
}
// Friend function to overload the operator +. This one takes two MyFancyInt. It is not needed. It can be commented out.
friend MyFancyInt operator+(MyFancyInt &x, MyFancyInt &y);
// Friend function to overload the operator +. This one takes an int and a MyFancyInt. It is needed for line /*6*/.
friend MyFancyInt operator+(int x, MyFancyInt &y);
// Friend function to overload the operator +. This one takes a MyFancyInt and an int. It is needed for line /*5*/.
friend MyFancyInt operator+(MyFancyInt &x, int y);
// Friend function to overload the output stream operator <<. It is needed for the printing in line /*7*/.
friend ostream& operator<<(ostream& os, const MyFancyInt& x);
// Overloading the operator =. It is needed for line /*2*/, /*5*/, and /*6*/.
MyFancyInt& operator=(const MyFancyInt &x);
private:
int* myValue;
};
MyFancyInt operator+(MyFancyInt &x, MyFancyInt &y)
{
cout << "MyFancyInt + MyFancyInt = " << x.myValue << " + " << y.myValue << "= " << *(x.myValue) << " + " << *(y.myValue) << endl;
MyFancyInt z=MyFancyInt(*(x.myValue) + *(y.myValue));
cout << "= " << *(z.myValue) << endl;
return z;
};
MyFancyInt operator+(int x, MyFancyInt &y)
{
cout << "int + MyFancyInt = " << x << " + " << y.myValue << " = " << x << " + " << *(y.myValue)<< endl;
MyFancyInt z = MyFancyInt(x + *(y.myValue));
cout << " = " << *(z.myValue) << endl;
return z;
};
MyFancyInt operator+(MyFancyInt &x, int y)
{
cout << "MyFancyInt + int = " << x.myValue << " + " << y << " = " << *(x.myValue) << " + " << y << endl;
MyFancyInt z = MyFancyInt(*(x.myValue) + y);
cout << " = " << *(z.myValue) << endl;
return z;
};
ostream& operator<<(ostream& os, const MyFancyInt& x)
{
os << *(x.myValue);
return os;
}
MyFancyInt& MyFancyInt::operator=(const MyFancyInt &x)
{
cout << "Entering the assigment operator." << endl;
myValue = x.myValue;
return *this;
};
int _tmain(int argc, _TCHAR* argv[])
{
MyFancyInt mfi1(1); /*1*/
MyFancyInt mfi2 = mfi1; /*2*/
MyFancyInt mfi3(mfi1); /*3*/
MyFancyInt mfi4; /*4*/
mfi4 = mfi3 + 2; /*5*/
mfi4 = 3 + mfi3; /*6*/
cout << mfi4 << endl; /*7*/
return 0;
}
The way your copy constructor is written, when you copy an object, both objects will be pointing to the same address and both will try to delete it.
I have an overloaded << operator from my reckful class implemented as follows:
ostream& operator << (ostream& os, const reckful& p)
{
os << p.PrintStuff();
return os;
}
PrintStuff() just being a member function of reckful that returns a string.
The way I understand things, if I were to write something like cout << reckobject << endl; in main(), cout << reckobject would take precedence and my overloaded << (using cout as the left operand and reckobject as the right operand) would return the ostream object os, leaving the expression os << endl; to be evaluated which would output the string and then end the line. So, the first << is the one I declared and the second is the standard << right?
However, my main question is... what is the sequence of events, which are the left and right operands, and which << operators are which when I run a statement like this:
cout << "reckful object = " << reckobject << "!" << endl;
Why does this work if there isn't an ostream object and a reckful object on either side of one << ?
Thanks.
If you notice standard way to implement << it returns the ostream itself. This is the critical piece
So something like
cout << "reckful object = " << reckobject << "!" << endl;
will be called once for
cout << "reckful object = "
This function call will return a ostream with which the second call will be made
namely
cout << reckobject;
so on an so forth.
You can test is out by implementing your << as
void operator << (ostream& os, const reckful& p)
{
os << 1;
}
in which case you can do
std::cout << p;
but not
std::cout << p << std::endl;
The operators make it harder to understand but consider this Point class
struct Point
{
Point& setX( int x) { X = x; return *this;}
Point& setY( int y) { Y = y; return *this;}
int X;
int Y;
};
The way setX and setY are defined, allows
Point p;
p.setX( 2 ).setY( 4 );
This is the same mechanism << is using to chain function calls.
Because each << returns a reference to cout. Because the operator << is left-associative, the calls are done from left to right, so
a << b << c
is equivalent to
(a << b) << c
which is equivalent1 to
operator<<(operator<<(a, b), c);
So in your example, you are doing
operator<<(operator<<(operator<<(operator<<(cout, "reckful object = "), reckobject), "!"), endl);
As you can see, each << depends on the return value of the previous << (or just cout in case there is no further left <<). If you change one of the return types of the <<s to void, you effectively stop any more << calls, because void can't be used as an argument to a function.
1 It's not exactly equivalent because in that example, all operator<< are free functions, whereas in reality, some can be member functions, so you could have a mix of member and non-member calls like
operator<<(a, b).operator<<(c);
or
operator<<(a.operator<<(b), c);