Printing private variables in Class via overloaded '<<' - c++

I'm switching from C to C++ and i have some basic but annoying problem with Class hermetization. I did some research here, but I'm probably really dumb and I can't use yor methods properly, could you help me?
The problem is printing private member of a class via overloaded '<<' operator.
Let's get to the code:
In file Vector.hh
#include <iostream>
class Vector {
double Val1, Val2, Val3;
public:
void PrintVector(Vector);
//There is also a constructor but it doesn't really matter
}
In File Vector.cpp
#include "Vector.hh"
#include <iostream>
void Vector::PrintVector(Vector Wek)
{
std::cout << Wek.Val1 << Wek.Val2 << Wek.Val3 << std::endl;
}
std::istream& operator >> (std::istream &Strm, Vector &Wek)
{
//It actually works with no problem so i'll pass it
}
std::ostream& operator << (std::ostream &Strm, Vector Wek)
{
Vector::PrintVector(Wek);
return Strm;
}
and in main.cpp
#include Vector.hh
#include <iostream>
using namespace std;
int main()
{
Vector Vector1;
cout << endl << " Start " << endl << endl;
cin >> Vector1;
cout << Vector1;
}
When I try to compile g++ says:
g++ -c -g -Iinc -Wall -pedantic -o obj/Vector.o src/Vector.cpp
src/Vector.cpp:12:37: error: no 'void Vector::PrintVector(Vector)' member function declared in class 'Vector'
void Vector::PrintVector(Vector Wek)
^
src/Vector.cpp: In function 'std::ostream& operator<<(std::ostream&, Vector)':
src/Vector.cpp:29:1: error: 'PrintVector' is not a member of 'Vector'
Vector::PrintVector(Wek);
make: Fatal error: Command failed for target `obj/Vector.o'
Could you please give me a hand with it so I learn basics properly?

Either a class function is static and not called on any particular class object, or it is non-static and must be called on an instance of the class, which can be used inside the function. You have mixed the approach. You need to select one of the two:
class Vector
{
static void PrintVector(const Vector& Wek)
{
std::cout << Wek.Val1 << Wek.Val2 << Wek.Val3 << std::endl;
}
};
// to call
Vector::PrintVector(Wek);
or
class Vector
{
void PrintVector() const
{
std::cout << Wek.Val1 << Wek.Val2 << Wek.Val3 << std::endl;
}
};
// to call
Wek.PrintVector();
Either is fine, but I would prefer the latter.
The other problem is how you have implemented the stream operator. This operator takes a stream to output the object to. You have called this stream Strm, but it is never used in your operator. Your print function is hardcoded to the cout stream.
I suggest you remove the PrintVector function and implement your operator as follows:
class Vector
{
friend std::ostream& operator << (std::ostream &Strm, const Vector& Wek);
};
std::ostream& operator << (std::ostream &Strm, const Vector& Wek)
{
Strm << Wek.Val1 << Wek.Val2 << Wek.Val3 << "\n";
return Strm;
}
Now you can output to any type of stream, such as a file stream. You also needed to declare the operator as a friend to allow it to access the private members.
I changed some parameters to reference to increase speed and also replaced endl with "\n" which is faster when writing to files (you can google why).
You may want to consider adding spaces between the output members, as this makes it easer to read back.
Hope this helps.

Your error is simple. You cannot use an instance method without an object. Try:
Wek.PrintVector();
Also, pass it by constant reference, don't copy.

General way to do this is to make operator<<() a friend function of the class. Friend function can access private members of the class. So operator<<() can directly access private members for printing them. Refer sample.
Defining a public function PrintVector for printing is a bad idea. Since it is public, user (developer using your class) might start using it instead of << operator. You don't want user to use it.

Related

Why is my overloaded << operator not working?

I'm trying to understand how to properly overload the "<<" operator so that I can use
std::cout << my_object;
to print useful debug messages. In particular, I need to have an implementation of << for each of my subclasses, so I'm declaring << to be virtual in the superclass.
Right now I'm stuck with the following piece of code
#include <iostream>
using namespace std;
class Shape {
public:
virtual ~Shape() { };
virtual ostream& operator<<(std::ostream &strm) = 0;
};
class Square : public Shape {
int size;
public:
Square() { size = 10; }
~Square() { }
ostream& operator<<(std::ostream &strm) {
return strm << "a square with size " << size;
}
};
int main() {
Square *my_square = new Square();
cout << "my_square is " << my_square << "\n";
}
which (I think) should be working, but doesn't. What I get when using "<<" is that the pointer value of my_square gets printed, rather than the result of the overloaded << .
$ ./a.out
my_square is 0xcacc20
What am I missing here?
operator<< can't be a member function. This is because of the order of the arguments. The stream has to come first.
When calling an overloaded operator, such as:
os << object;
the compiler will attempt to look up both
os.operator<<(object);
and
operator<<(os, object);
(The rules for this can be rather complex, I won't attempt to describe them here.)
Because the stream always comes on the left, your member function will never be found, since it would have to be called as:
object.operator<<(os);
You need to write a free function like:
ostream& operator<<(std::ostream &strm, Square const& square) {
return strm << "a square with size " << square.size();
}
(where Square::size() returns the size member).
Then you need to remember to dereference your pointer too:
std::cout << *my_square << '\n';
Although I see no reason to be dynamically allocating my_square in this example anyway. Just stick it on the stack as a local variable.
If the aim here is ultimately to be able to print any Shape&, and have the printed output follow the "real" type, you would need to create:
virtual std::ostream& print(std::ostream&) const = 0;
in the Shape base class, and override it in each derived class, then have a free function:
std::ostream& operator<<(std::ostream& os, Shape const& shape)
{
return shape.print(os);
}
It is often advised to make all binary operators on your type non-member functions, so that both arguments are treated equally, and the operation remains commutative. See Scott Meyers, Effective C++ (3rd Edition), Item 24, (or find a summary online).
As noted by others, the problem is that operator << can't be member function (because of the order of arguments). The canonical way to do this is to have operator <<(const Shape&) call a virtual function in Shape
class Shape {
friend ostream& operator<<(std::ostream& str, const Shape& shape);
virtual void do_print(ostream& str) = 0;
public:
virtual ~Shape() { };
};
ostream& operator<<(std::ostream& str, const Shape& shape) {
shape.do_print(str);
return str;
}
Note that it is legal to have do_print be private, even though it is going to be (must be) overridden by derived classes. You could make it protected though if you like.
What am I missing here?
You have created operator which will get you class as a first argument and stream as the second.
my_square << std::cout;
I'd create free function and to make it dynamic I'd call some virtual method in it

Why and how to overload operator<< for printing

I have written a program for implementation of stack. And I have one display function in it.
This is how I wrote display function at first:
template <class t>
void Mystack<t>::display()
{
for (int i = 0; i <= top; i++)
{
std::cout << input[i] << " ";
}
}
Then I was suggested by developers to write a display function to be more generic. So I wrote display function as:
template <class T>
void Mystack<T>::display(std::ostream &os) const
{
for (int i = 0; i <= top; i++)
{
os << input[i] << " ";
}
}
As per my understanding the benefit of writing above function is that now I have a generic display function which I can use to display data to console or to a file too.
Question 1: Is my understanding correct?
Now another suggestion is to write function something like:
template <typename T>
friend std::ostream& operator<<(std::ostream& s, Mystack<T> const& d) {
d.display(s);
return s;
}
Question 2: What is the benefit of having above display function? What exactly will I be able to achieve by having above display function?
For question 1, your understanding is correct, but the real improvement comes from question 2's suggestion of writing:
template <typename T>
friend std::ostream& operator<<(std::ostream&, Mystack<T> const& );
That will let anybody stream objects of your type in the same way they would stream anything else:
std::cout << "Hi, my stack is " << stack << ", it has size " << stack.size();
to any stream they want:
some_file << "Result of computation is: " << stack;
std::cerr << "Error, invalid stack: " << stack << ", expected: " << some_other_thing;
Firstly - yes. By taking the std::ostream& parameter, you can output to any derived stream too, like std::ofstream, or std::cout, std::cerr.
Using operator<< allows you to, use that operator. Consider:
mystack<int> stackOfInts;
//...
std::cout << "Stack contents:" << std::endl << stackOfInts << std::endl;
It's just more idiomatic than a 'standard' function call.
Returning the stream allows the chaining of the operator, as in the above example. The chaining is effectively passing the result of a call to operator<< into another one:
operator<<( operator<<("Stack contents:", std::endl), stackOfInts ) );
If this overloaded call doesn't also return an std::ostream&, then there is no way to do:
operator<<( resultOfAbove, std::endl );
Declaring the function a friend allows its definition to use private members. Without this, you would have to do something like write a public getter for each private member.
Both display function are basically the same. The different is the way you call the function.
With first function, you call function in usual way:
std::cout<<"This is MyStack (with first method): ";
m.display(std::cout); //function call
std::cout<<std::endl;
With second function, you call function with operator "<<":
std::cout<<"This is MyStack (with second method): "
<<m //function call
<<std::endl;
But I personally prefer the second one. Since it's more familiar to me.
As with regard to Question 2, this is the way to go if you have a base class and lots of derived classes, and want to write operator<< only once, in the base class. Then, if you declare the display() function as virtual along your class hierarchy, you can choose at runtime the correct display function. That is, if you have something like
Derived foo;
std::cout << foo;
then Base::operator<< will call the Derived::display(), because it is marked as virtual and foo is passed by reference. This is the way to go when you have a class hierarchy and don't want to overload operator<< for each derived class.
This is a common trick in avoiding code duplication. See
Making operator<< virtual?
on StackOverflow for more details.

Error: No operator << matches these operands?

I was practicing some c++ (trying to leave Java), and I stumbled on this annoying error saying:Error: No operater << matches these operands. I've searched this website for a clear answer and no luck, I did find that I'm not the only one.
This error is in my .cpp file, there are other errors, but I'm not paying any mind to them right now.
void NamedStorm::displayOutput(NamedStorm storm[]){
for(int i = 0; i < sizeof(storm); i++){
cout << storm[i] << "\n";
}
}
Something is up with the "<<" im not sure whats going on.
Since you are trying cout a class object you need to overload <<
std::ostream& operator<<(ostream& out, const NamedStorm& namedStorm)
You must overload the << operator in order to redirect your object into a stream.
You can overload as a member function, but in this case you must use the syntax object << stream in order to use that overloaded function.
If you wish to use this syntax stream << object then you must overload the << operator as a 'free' function, that is, not a member of your NamedStorm class.
Here is a working example:
#include <string>
#include <iostream>
class NamedStorm
{
public:
NamedStorm(std::string name)
{
this->name = name;
}
std::ostream& operator<< (std::ostream& out) const
{
// note the stream << object syntax here
return out << name;
}
private:
std::string name;
};
std::ostream& operator<< (std::ostream& out, const NamedStorm& ns)
{
// note the (backwards feeling) object << stream syntax here
return ns << out;
}
int main(void)
{
NamedStorm ns("storm Alpha");
// redirect the object to the stream using expected/natural syntax
std::cout << ns << std::endl;
// you can also redirect using the << method of NamedStorm directly
ns << std::cout << std::endl;
return 0;
}
The function which is called from the free redirection overload must be a public method of NamedStorm (in this case we are calling the operator<< method of the NamedStorm class), OR the redirection overload must be a friend of the NamedStorm class in order to access private fields.

Using ofstream* wrapper class with overloaded << operator on endl

C++
This is an attempt to make a class that mimics the output behavior of using the << operator of an ofstream, as far as being able to use std::endl and write strings is concerned. The class has a single data member, the ofstream pointer. The class has two overloaded << operators, one that takes an std::string and another that takes a pointer to a function, whose argument is an ostream reference and returns an ostream reference. That is the signature of std::endl, according to this. Technically, the below program works with the given input. It is able to print to file, two lines of text separated by two std::endls. However, I want my non-string parameter overloaded << operator to accept std::endl only, not something that merely matches its signature. I tried various combinations of placing std::endlin the argument list, with and without * and with and without &, but I got compiler errors for every combination. C++11 answers are also welcome.
#include <fstream>
#include <iostream>
#include <string>
class TextOut
{
public:
TextOut(std::ofstream* ofsPar) : ofs(ofsPar) {}
TextOut& operator<<(std::string s)
{
*ofs << s;
return *this;
}
TextOut& operator<<(std::ostream& (*endlPar) (std::ostream& os))
{
*ofs << std::endl;
return *this;
}
private:
std::ofstream* ofs;
};
int main()
{
std::cout << "Enter filename: ";
std::string filename;
std::cin >> filename;
std::ofstream myofstream(filename.c_str());
TextOut myTextOut(&myofstream);
myTextOut << "Hello," << std::endl << std::endl << "spacious world.";
return 0;
}
Output:
Hello,
spacious world.
If I look at my ostream header file I see this for endl:
template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{
return flush(__os.put(__os.widen('\n')));
}
so it looks like you would need to inherit from basic_ostream to make this work. Not sure you really want to do that.
As far as I know there is no way to enforce a parameter to be a specific value at compile time.
If compile-time enforcement is not a requirement, you could use a simple assert like this to enforce that the parameter is std::endl:
assert(static_cast<std::ostream& (*) (std::ostream& os)>(&std::endl) == endlPar);

Operator overloading << in C++

I wrote this simple program to practice overloading.
This is my code:
#include <iostream>
#include <string>
using namespace std;
class sex_t
{
private:
char __sex__;
public:
sex_t(char sex_v = 'M'):__sex__(sex_v)
{
if (sex_v != 'M' && sex_v != 'F')
{
cerr << "Sex type error!" << sex_v << endl;
__sex__ = 'M';
}
}
const ostream& operator << (const ostream& stream)
{
if (__sex__ == 'M')
cout << "Male";
else
cout << "Female";
return stream;
}
};
int main(int argc, char *argv[])
{
sex_t me('M');
cout << me << endl;
return 0;
}
When I compile it, it print lots of error messages:
The error message was in a mess.
It's too hard for me to found a useful message.
sex.cpp: 在函数‘int main(int, char**)’中:
sex.cpp:32:10: 错误: ‘operator<<’在‘std::cout << me’中没有匹配
sex.cpp:32:10: 附注: 备选是:
/usr/include/c++/4.6/ostream:110:7: 附注: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostre
The argument and return from operator<< are non-const. Also it needs to be a non-member- you have written an overload for me << cout, not cout << me. Also, identifiers leading with two underscores are reserved for the implementation and using them is Undefined Behaviour.
"C++ Primer 4th Edition" Chapter 14 section 14.2 Input and Output Operators:
IO Operators Must Be Nonmember Functions, We cannot make the operator a member of our own class. If we did, then the left-hand operand would have to be an object of our class type:
// if operator<< is a member of Sales_item
Sales_item item;
item << cout;
The general skeleton of an overloaded output operator is
// general skeleton of the overloaded output operator
ostream&
operator <<(ostream& os, const ClassType &object)
{
// any special logic to prepare object
// actual output of members
os << // ...
// return ostream object
return os;
}
The first parameter is a reference to an ostream object on which the output will be generated. The ostream is nonconst because writing to the stream changes its state. The parameter is a reference because we cannot copy an ostream object.
The second parameter ordinarily should be a const reference to the class type we want to print. The parameter is a reference to avoid copying the argument. It can be const because (ordinarily) printing an object should not change it. By making the parameter a const reference, we can use a single definition to print const and nonconst objects.
The return type is an ostream reference. Its value is usually the ostream object against which the output operator is applied.
EDIT:
I tried to modify your code, and if you use __sex__ as sex_t's private member, you should write another get function to get the 'M' or 'F', and if you call it in your operator<< function, you will probably get an error, because a const reference could only call a const function, so you should make your get function a const function, just for reminde:)
When overloading for streams, you declare a << operator globally and/or as a friend (with benefits) to your class so it can access its 'private members' (ooh...). You can declare a friend inside the class to declare it globally. Do not use const on the streams.
Next, use the passed stream in your overload. In your method, you use cout when you would have used it anyway by just using the stream argument.
I have not tested this, but see if it works for you.
class sex_t
{
private:
char __sex__;
public:
sex_t(char sex_v = 'M'):__sex__(sex_v)
{
if (sex_v != 'M' && sex_v != 'F')
{
cerr << "Sex type error!" << sex_v << endl;
__sex__ = 'M';
}
}
friend ostream& operator << (ostream& stream, sex_t& sex);
};
ostream& operator << (ostream& stream, sex_t& sex)
{
if (__sex__ == 'M')
stream << "Male";
else
stream << "Female";
return stream;
}