Cannot access private member declared in class - c++

I am working with operator overloads for the first time and am setting up the overload for the extraction operator (<<). I'm stuck in one of two errors that are preventing me from continuing. The code is as follows:
ostream &operator << (ostream &output, const Distance &d1)
{
if (d1.miles > 0)
{
output << d1.miles << "m ";
}
if (d1.yards > 0)
{
output << d1.yards << "y ";
}
if (d1.feet > 0)
{
output << d1.feet << "\' ";
}
output << d1.inches << "\"";
return (output);
}
The overload is declared as a friend in the header file as follows:
friend ostream &operator<< (ostream output, const Distance &d1);
The first issue I encounter is that when the overload is formatted this way (which is as far as I can tell, the correct way) it does not allow me to access the miles, yards, feet, or inches member data, despite the function being set as a friend in the header file.
If I change the overload to read :
ostream &operator << (ostream output, const Distance &d1)
{
if (d1.miles > 0)
{
output << d1.miles << "m ";
}
if (d1.yards > 0)
{
output << d1.yards << "y ";
}
if (d1.feet > 0)
{
output << d1.feet << "\' ";
}
output << d1.inches << "\"";
return (output);
}
Then the overload works correctly, but it does not work in my main function as it returns the error:
error C2248: 'std::basic_ostream<_Elem,_Traits>::basic_ostream' : cannot access private member declared in class 'std::basic_ostream<_Elem,_Traits>'
for every instance of cout in the function. Plus, the previous examples I have show that this would be incorrect. What am I doing wrong in the first code example that is preventing me from accessing the private member data? I've looked at several other instances of this being asked on various sites, but nothing quite matches what I am getting. I have tried compiling with Visual Studio Express 2012 and g++, both return the error.

The declaration inside the class definition should be:
friend ostream &operator<< (ostream &output, const Distance &d1);
// ^--- important
The error in your first attempt is because when you write a function ostream &operator<< (ostream &output, const Distance &d1), this is not the same function you friended because it has different arguments.
The second attempt should have various errors , as it is not permitted to pass ostream by value.

Related

overloading operator << c++, I am trying to cout the element of class

I am writing this code
ostream& operator <<(ostream& out, Box& B){
return B.l +" "+B.b +" "+B.h +endl;
};
The error I get is
Solution.cpp:40:46: error: ‘std::ostream& Box::operator<<(std::ostream&, Box&)’ must have exactly one argument ostream& operator <<(ostream& out, Box& B){ ^
can someone explain what's wrong? I dont understand.
thanks for your help :)
It seems you mean the following
std::ostream & operator <<( std::ostream& out, const Box& B) {
return out << B.l << " " << B.b << " " << B.h;
}
provided that all used in the operator data members are public data members of the class Box. The operator shall be declared and defined outside the class definition.
If one of the used data members is a private data member of the class then the function should be a friend function of the class and shall be declared (and may be defined) in the class definition. For example
class Box
{
//...
friend std::ostream & operator <<( std::ostream& out, const Box& B) {
return out << B.l << " " << B.b << " " << B.h;
}
//...
};
Pay attention to that it is better to remove in the return statement the operand std::endl. In this case 1) the operator will be more flexible because you can output additional information in the same line and 2) this statement
std::cout << box;
will not confuse readers of the code because they will not see the operand std::endl.
Without this operand in the operator definition in the caller of the operator you can write
std::cout << box << std::endl;
and this statement more clear expresses the intention of the programmer.
It should probably be:
std::ostream& operator<<(std::ostream& out, Box const& B){
out << B.l << " " << B.b << " " << B.h << std::endl;
return out;
};
Full code should look like:
#include <iostream>
class Box {
int l;
int b;
int h;
friend std::ostream& operator<<(std::ostream& out, Box const& B);
};
std::ostream& operator<<(std::ostream& out, Box const& B){
out << B.l << " " << B.b << " " << B.h << std::endl;
return out;
}
int main() {
return 0;
}
Demo
To output a type T to std::ostream, you have to declare standalone operator, which returns reference to that stream
std::ostream& operator<<(std::ostream& out, const T& B)
{
out << B.l << " " << B.b << " " << B.h << '\n';
return out;
}
This operation cannot be member operator because member operator use their class as first argument, therefore it might be necessary declare it as a friend of class T.
Avoid using endl in such operators if not extremely necessary, that manipulator calls out.flush(). If you want new line added, use new-line character.

Error with << operator overload returning a std::string

I'm having troubles understanding the reason why the compiler accuses error, when the return type of a << operator overload is std::string. Could you please help me understand?
Bellow is an reproducible example, which gives a gigantic error.
class XY
{
int X__;
int Y__;
public:
XY(int x, int y):X__(x), Y__(y){}
~XY(){}
std::string operator<<(const XY_cartesiano& c)
{
std::stringstream ss;
ss << "{ " << X__ << ", " << Y__ << " }";
return ss.str();
}
int x() const{return X__;}
int y() const{return Y__;}
};
void main()
{
XY a(1,2);
std::cout << a;
}
Let's take something like this as an example:
cout << "My number is " << 137 << " and I like it a lot." << endl;
This gets parsed as
((((cout << "My number is ") << 137) << " and I like it a lot.") << endl);
In particular, notice that the expression cout << "My number is " has to evaluate to something so that when we then try inserting 137 with << 137 the meaning is "take 137 and send it to cout."
Imagine if cout << "My number is " were to return a string. In that case, the << 137 bit would try to use the << operator between a string on the left-hand side and an int on the right-hand side, which isn't well-defined in C++.
The convention is to have the stream insertion operator operator << return a reference to whatever the left-hand side stream is so that these operations chain well. That way, the thing on the left-hand side of << 137 ends up being cout itself, so the above code ends up essentially being a series of chained calls to insert things into cout. The signature of these functions therefore usually look like this:
ostream& operator<< (ostream& out, const ObjectType& myObject) {
// ... do something to insert myObject into out ... //
return out;
}
Now, everything chains properly. Notice that this function is a free function, not a member function, and that the left-hand side is of type ostream and the right-hand side has the type of your class in it. This is the conventional way to do this, since if you try overloading operator << as a member function, the left-hand side will be an operand of your class type, which is backwards from how stream insertion is supposed to work. If you need to specifically access private fields of your class in the course of implementing this function, make it a friend:
class XY {
public:
...
friend ostream& operator<< (ostream& out, const XY& myXY);
};
ostream& operator<< (ostream& out, const XY &myXY) {
...
return out;
}
Correct way to overload << operator in your case is
ostream& operator<<(ostream& os, const XY& c)
{
os << c.X__ <<" "<< c.Y__ ;
return os;
}
You have overloaded operator<< in a way that's incompatible with the conventions you must follow when you intend to use the operator with a std::ostream object like std::cout.
In fact, your operator<<'s signature has nothing to do with streams at all! It is just a member function of XY which takes another XY (which it then does not use), returns a string and has an unsual name. Here's how you would theoretically call it:
XY a(1,2);
XY b(1,2);
std::string x = (a << b);
The correct way to overload operator<< for use with streams is to make the operator a non-member function, add a stream reference parameter and return a stream reference to the stream argument. You also do not need a string stream; you write directly to the stream you get:
#include <iostream>
class XY
{
int x;
int y;
public:
XY(int x, int y) : x(x), y(y) {}
int X() const { return x; }
int Y() const { return y; }
};
std::ostream& operator<<(std::ostream& os, XY const& c)
{
os << "{ " << c.X() << ", " << c.Y() << " }";
return os;
}
int main()
{
XY a(1,2);
std::cout << a;
}

<< operator overloading as a class method in c++

I want to overload the << operator for my class Complex.
The prototype is the following:
void Complex::operator << (ostream &out)
{
out << "The number is: (" << re <<", " << im <<")."<<endl;
}
It works, but I have to call it like this: object << cout for the standart output.
What can I do to make it work backwards, like cout << object?
I know that the 'this' pointer is by default the first parameter sent to the method so that's why the binary operator can work only obj << ostream. I overloaded it as a global function and there were no problems.
Is there a way to overload the << operator as a method and to call it ostream << obj?
I would just use the usual C++ pattern of free function. You can make it friend to your Complex class if you want to make Complex class's private data members visible to it, but usually a complex number class would expose public getters for real part and imaginary coefficient.
class Complex
{
....
friend std::ostream& operator<<(std::ostream &out, const Complex& c);
private:
double re;
double im;
};
inline std::ostream& operator<<(std::ostream &out, const Complex& c)
{
out << "The number is: (" << c.re << ", " << c.im << ").\n";
return out;
}
You could write a free stand operator<< function, try:
std::ostream& operator<< (std::ostream &out, const Complex& cm)
{
out << "The number is: (" << cm.re <<", " << cm.im <<")." << std::endl;
return out;
}
You can define a global function:
void operator << (ostream& out, const Complex& complex)
{
complex.operator<<(out);
}

Operator+= on vector failed

template <class ElementType,int Dimension=1>
class Vector : public vector<ElementType> {
public:
Vector & operator+= (const Vector & a){
cout << " a " << a << endl;
transform (this->begin(), this->end(), a.begin(), this->begin(), plus<ElementType>());
return *this;
};
friend ostream & operator<< (ostream & stream, Vector t) {
stream << "(";
copy (t.begin(), t.end()-1, ostream_iterator<ElementType>(stream,","));
return stream << *(t.end()-1) << ")";
};
};
1) During runtime I get the error message:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
I've found that this message is caused by cout << " a " << a << endl;
2) Without that cout << ..... operation finished successfully but some garbage is added to this instead of contents of a.
Any suggestions?
There exists std::valarray for this purpose.
This output operator
friend ostream & operator<< (ostream & stream, Vector t)
can possibly cause a bad_alloc because it copies the Vector parameter.
You can try this instead
friend ostream & operator<< (ostream & stream, const Vector& t)
to avoid that.
To avoid the problem with an empty vector not having an end()-1 you might want to put the output inside an if (!t.empty()).
And finally this expression *(t.end()-1) can be simplified to t.back().

Getting the compiler to perceive << as defined for a specific class

I edited a post of mine with this question, yet got no answers.
I overloaded << for a class, Score (defined in score.h), in score.cpp.
ostream& operator<< (ostream & os, const Score & right)
{
os << right.getPoints() << " " << right.scoreGetName();
return os;
}
(getPoints fetches an int attribute, getName a string one)
I get this compiling error for a test in main(), contained in main.cpp
binary '<<' : no operator found which takes a right-hand operand of type 'Score' (or there is no acceptable conversion)
How come the compiler doesn't 'recognize' that overload as valid? (includes are proper)
Thanks for your time.
EDIT:
As requested, code causing the error:
cout << ":::::\n" << jogador.getScore() << endl;
jogador is a Player object, which contains a Score one. getScore returns that attribute.
Perhaps you didn't declare your operator<< in score.h? It should normally contain something like:
ostream& operator<< (ostream & os, const Score & right);
Edit: More accurately, that should be:
std::ostream &operator<<(std::ostream &os, const Score &right);
You definitely should not have a using namespace std; in a header, so you need the std:: for it to work correctly.
Try declaring operator<< as a friend function in your class:
struct Score
{
friend ostream& operator<<(ostream& output, const Score& right);
};
This will allow your Score structure to fit nicely into printing statements:
Score my_score;
cout << my_score << endl;
When in doubt, check the C++ FAQ.