Hello I'm in the process of learning about operator overloading and friend functions.
I've declared the operator<< function as a friend of my class in a .h file but I still cant access the private member variables from the function definition in a .cpp file
My code is as follows:
Test.h
class Test
{
private:
int size;
public:
friend ostream& operator<< (ostream &out, Test& test);
};
Test.cpp
#include "Test.h"
#include <iostream>
using namespace std;
ostream& operator<< (ostream& out, Test& test)
{
out << test.size; //member size is inaccessible!
}
Apparently size is inaccessible although I've already made the operator<< function a friend of my class. I've Googled a bit and haven't found anything so can anyone help me out? Thanks.
Note: If I move the class definition to the .cpp file everyone works so I assume my problem has something to do with multiple files.
In c++ the scope of the declaration go from top to bottom. So if you include first Test.h and after that <iostream> the friend declaration has does not know about the type std::ostream.
The solution:
Test.h:
#include <iostream>
class Test
{
private:
int size;
public:
friend std::ostream& operator<< (std::ostream &out,const Test& test);
};
Test.cpp:
#include "Test.h"
std::ostream& operator<< (std::ostream& out,const Test& test)
{
out << test.size;
return (*out);
}
Note that the #include <iostream> has been moved from Test.cpp to Test.h and the argument of the global operator << takes const Test& test. The const makes the operator work for rvalues.
Related
So, I have recently approched OOP in c++ through university and I found myself with a few problems.
I gave a shot at overloading the ostream operator << and found myself with some problems to solve.
First was that doing the overloading as ostream& operator<<(ostream& outs, const Test&); carries a problem described as \src\Test.h:15:48: error: 'std::ostream& test::Test::operator<<(std::ostream&, const test::Test&)' must take exactly one argument ostream& operator<<(ostream& outs, const Test&);, so, just like I did with the operator == removed the second argument. But once i Try to build the following code i get the error: \src\main.cpp:9:10: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&' cout << t;.
I read this error but can't comprhend it, what should I do and what is the mistake I'm doing?
Test.h
#include <iostream>
#include <cstring>
using namespace std;
#ifndef SRC_TEST_H_BECCIO
#define SRC_TEST_H_BECCIO
namespace test {
class Test {
private:
string mStr;
public:
Test(string str);
string getString(){return this->mStr;};
ostream& operator<<(ostream& outs);
};
} /* namespace test */
#endif /* SRC_TEST_H_BECCIO */
Test.cpp
#include "Test.h"
namespace test {
Test::Test(string str) {
this->mStr=str;
}
ostream& Test::operator<<(ostream& outs){
outs << this->getString()<<endl;
return outs;
}
} /* namespace test */
main.cpp
#include <iostream>
#include "Test.h"
using namespace std;
using namespace test;
int main() {
Test t("let's hope this goes well");
cout << t;
return 0;
}
It looks like the order of the arguments is backwards. See https://learn.microsoft.com/en-us/cpp/standard-library/overloading-the-output-operator-for-your-own-classes.
Try this declaration, and a similar implementation:
friend ostream& operator<<(ostream& os, Test t);
While doing some code practice myself I got some Error
student.h file
#pragma once
class Student {
public:
Student() = default;
Student(int id, const char* name, int score);
Student(const Student& s);
Student(Student&& other);
Student& operator=(Student&& other);
virtual ~Student();
**friend std::ostream & operator<<(std::ostream & os, const Student & rhs);**
void print();
private:
int mId;
char* mName;
int mScore;
size_t mSize;
};
student.cpp file
#include "student.h"
#include <iostream>
#include <string>
... //bunch of constructors, override...
std::ostream & operator<<(std::ostream& os, const Student & rhs)
{
os << rhs.mId << rhs.mName << rhs.mScore ; // Compile Error: Cannot Access Student Member(rhs.mId, rhs.mName...)
return os;
}
The Error i got was i cannot access Student class member despite I declared it friend function in student.h
Strange to me, It compiled successfully if i declare #include<iostream> statement in student.cpp file like this
#include <iostream> //change position <iostream> and "student.h"
#include <string>
#include "student.h"
... //bunch of constructors, override...
std::ostream & operator<<(std::ostream& os, const Student & rhs)
{
os << rhs.mId << rhs.mName << rhs.mScore ; //Compile successfully
return os;
}
So, why #include statement sequences are matters? i thought #include statement just copy-paste to my cpp file.
And it also compiled successfully when i declare #include<iostream> to student.h,
so when i include some #include things the Best-case is declare it to header-file?
Could you give me some advise?
I compiled my program in Visual Studio 2019.
In student.h add an include for iosfwd:
#pragma once
#include <iosfwd>
class Student ...
This will ensure correct resolution of the std::ostream symbol and recognize the ostream operator you defined as the one you declared as a friend.
The iosfwd header contains forward declarations of the symbols in iostream header, and it is defined for exactly this scenario.
In C++ we must declare anything before using it.
So your problem is that you haven't declared std::ostream but you have used it in student.h.
An suitable solution is to #include <iostream> in the beginning of student.h, below #pragma once.
You can also put these before class Stduent:
namespace std
{
class ostream;
}
This is called forward declaration.
I am receiving the error "declaration of reference variable 'operator' requires an initialization" in my main.cpp.
In the constructor have already tried including:
friend ostream& operater << (ostream& out, Coins& c)
in the header file, however the error still occurs. Also, I tried adding
#include <ostream>
#include <iostream>
in the header file.
This is the function I am using.
myfile.h
ostream& operater << (ostream& out, Coins& c){
c.print(out);
return out;
}
Header file:
#ifndef CART_H
#define CART_H
#include "Tops.h"
#include <iostream>
#include <vector>
using namespace std;
class Cart
{
public:
Cart();
void addTop(Tops& top);
friend ostream& operator<<(ostream& ostr, const Cart& c);
private:
vector<Tops> tops;
};
#endif
Implementation file:
#include "Cart.h"
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
Cart::Cart() { }
void Cart::addTop(Tops &top)
{
tops.push_back(top);
}
ostream& operator<<(ostream &ostr, const Cart &c)
{
ostr << "TOPS IN CART:\n-------------\n";
for (auto const top : c.tops) {ostr << top << endl; } // no match for 'operator<<'
return ostr;
}
Problem: I keep getting a "no match for operator<<" error and I have no idea why, and I also have no idea what it means. When I google this error, what has caused the error in other people's codes does not apply to mine.
In your declaration you have stated that the Cart argument will be const:
friend ostream& operator<<(ostream& ostr, const Cart& cart);
but your definition does not:
ostream& operator<<(ostream &ostr, Cart &c)
They need to match (either both const or both not - both const would be right here) for the friend declaration to be of any use.
Disclaimer: I'm new to programming in c++, I've read through dozens of forums, and can't find an answer to my specific question.
I've included the header and definition files for a Point class below and a main function that calls an overloaded ostream to print the Point. I can't find the correct syntax for the definition for the non member overloaded operator<<. If I have it the way it's posted, I get error message:
undefined reference to `Clustering::operator<<(std::ostream&, Clustering::Point const&)
If I add Clustering:: before the operator<< I get error message:
std::ostream& Clustering::operator<<(std::ostream&, const Clustering::Point&)' should have been declared inside 'Clustering'
std::ostream &Clustering::operator<<(std::ostream &os, const ::Clustering::Point &point)
How is this code supposed to be written?
Point.h file:
#ifndef CLUSTERING_POINT_H
#define CLUSTERING_POINT_H
#include <iostream>
namespace Clustering {
class Point {
int m_dim; // number of dimensions of the point
double *m_values; // values of the point's dimensions
public:
Point(int);
friend std::ostream &operator<<(std::ostream &, const Point &);
};
}
#endif //CLUSTERING_POINT_H
Point.cpp file:
#include "Point.h"
//Constructor
Clustering::Point::Point(int i)
{
m_dim = i;
m_values[i] = {0};
}
std::ostream &operator<<(std::ostream &os, const Clustering::Point &point) {
os << "Test print";
return os;
}
Main.cpp:
#include <iostream>
#include "Point.h"
using namespace std;
using namespace Clustering;`
int main() {
Point p1(5);
cout << p1;
return 0;
}
You need to put your std::ostream &operator<< in Clustering namespace in Point.cpp
namespace Clustering {
std::ostream &operator<<(std::ostream &os, const Clustering::Point &point)
{
// ...
}
}