I thought that friend functions could access class variables as in how I try to do v.x, v.y, v.z in the << function. But it doesn't compile. It says it's unable to resolve identifier at those lines.
Also I'm trying to learn how to use namespaces. Even though I use the namespace vec in the implementation file I still have to include Vector:: before everything so what's the point?
Header file:
#ifndef VECTOR_H
#define VECTOR_H
namespace vec {
class Vector {
private:
double x, y, z;
public:
Vector(double, double, double);
friend std::ostream& operator<<(std::ostream&, const Vector&);
};
}
#endif /* VECTOR_H */
.cpp file:
#include "Vector.h"
#include <iostream>
using namespace vec;
//Constructor
Vector::Vector(double x1 = 0, double y1 = 0, double z1 = 0) {
x = x1;
y = y1;
z = z1;
}
//Operators
std::ostream& operator<<(std::ostream& out, const Vector& v) {
out<<"<"<<v.x<<", "<<v.y<<", "<<v.z<<">";
return out;
}
Friend functions aren't member functions, and operator<< needs to not be a member in order to have a left side of ostream. Change it to a free function:
std::ostream& operator<<(std::ostream& out, Vector v) {
^^ no qualification
I would also take the vector by const reference instead of by value.
Your friend function belongs to the namespace vec and must be defined as such.
Change it to:
std::ostream &vec::operator << (std::ostream &out , const Vector &v) { //etc
Related
This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 6 years ago.
//main()
#include <iostream>
#include "Circle.h"
#define PI 3.1415965 //defining the pi number
using namespace std; //I want to create a class that has the characteristics of a circle
int main()
{
Circle c1(1); //making a class object
cout<<c1; //using the operator<< after overloading it
return 0;
}
//circle.h
#include <iostream> //I'm just practicing with these things so my code will probably have some mistakes but I really cannot understand where is the right place for the operator<< because I receive errors all the time
using namespace std;
class Circle //creating the class circle
{
public:
Circle(); //constructor with zero members
Circle(float r); //constructor with one member
float getPerimetre(); //getting the perimeter of the circle
float getArea(); //getting the area of the circle
friend ostream &operator<<(ostream &mystream, Circle &p); //making the operator<<
private:
float radius; //private members
};
#endif // CIRCLE_H
//circle.cpp
#include "Circle.h"
#include <iostream>
#define PI 3.14159265 //defining the pi number
using namespace std;
Circle::Circle() //creating the constructor with zero members
{
radius=0;
Circle::Circle(float r) //creating the constructor with one member
{
radius=r;
}
float Circle::getPerimetre() //explaining the functions get perimetre
{
return (2*PI*radius);
}
float Circle::getArea() //and get area
{
return (PI*radius*radius);
}
ostream &operator<<(ostream &mystream, Circle &p) //i'm not sure if this is the right place to write this
{
mystream<<radius<<", "<<getPerimetre()<<", "<<getArea()<<endl;
return mystream;
}
out from all the things that I've read I really cannot understand where is the correct spot to write this operator and why I keep receiving errors when I run the project. I am new to this and also to this site so any help would be very apreciated
Your operator<< is at good place, however since it isn't member function you can't access members without object:
p.radius instead of radius
p.getPerimetre() instead of getPerimetre()
p.getArea() instead of getArea()
ostream &operator<<(ostream &mystream, Circle &p) //i'm not sure if this is the right place to write this
{
mystream<<radius<<", "<<p.getPerimetre()<<", "<<p.getArea()<<endl;
return mystream;
}
friend ostream &operator<<(ostream &mystream, Circle &p);
should be
friend ostream &operator<<(ostream &mystream, const Circle &p);
and the implementation should look like
ostream &operator<<(ostream &mystream, const Circle &p)
{
mystream<<p.radius<<", "<<p.getPerimetre()<<", "<<p.getArea()<<endl;
return mystream;
}
this also requires that you classify getPerimetre() and getArea() as const functions in your class declaration
class Circle {
public:
// ...
float getPerimetre() const;
// ^^^^^
float getArea() const;
// ^^^^^
// ...
};
and definition
float Circle::getPerimetre() const {
// ^^^^^
return (2*PI*radius);
}
float Circle::getArea() const {
// ^^^^^
return (PI*radius*radius);
}
I tried to make friend ostream function. The compiler say i cannot access private member of the class, even though i declared it as friend. I read a similar question and it say the problem is with the namespcaes.(the question: C++ friend function can't access private members)
My Code is below:
header:
#include <iostream>
#include <string>
//using namespace std;
namespace biumath
{
#ifndef BIUMATH_H
#define BIUMATH_H
class Assignment
{
private:
int **m_varArray;
int m_rowsOfVarArray;
public:
Assignment(); //1
Assignment(char symbol, double value); //2
bool containsValueFor(char symbol) const; //3
double valueOf(char symbol) const; //4
void add(char symbol, double val); //5
friend std::ostream& operator<< (std::ostream& out,
const Assignment& assignment);
};
}
#endif
cpp:
#include <iostream>
#include "biumath.h"
using namespace biumath;
using std::cout;
using std::endl;
ostream& operator<< (ostream& out,
const Assignment& assignment){
out<<assignment.m_rowsOfVarArray<<std::endl;
//return the stream. cout print the stream result.
return out;
}
or better yet, avoid all unnecessary friendships by deferring to a public utility method (this also has benefits when your Assignment is a polymorphic base class):
in header file:
namespace biumath
{
class Assignment
{
private:
int **m_varArray;
int m_rowsOfVarArray;
public:
Assignment(); //1
Assignment(char symbol, double value); //2
bool containsValueFor(char symbol) const; //3
double valueOf(char symbol) const; //4
void add(char symbol, double val); //5
void write(std::ostream& os) const; // <=== public helper
};
// free function overload which defers to helper.
// NOTE: it's in the biumath namespace so ADL will find it
inline std::ostream& operator<< (std::ostream& out,
const Assignment& assignment){
assignment.write(out);
return out;
}
}
in CPP file:
namespace biumath {
void Assignment::write(std::ostream& os) const {
os << m_rowsOfVarArray << std::endl;
}
}
You may define the operator in the enclosing namespace (in your case in the global namespace) but you have to use the qualified name.
Thus define the operator like
ostream& biumath::operator<< (ostream& out,
const Assignment& assignment){
out<<assignment.m_rowsOfVarArray<<std::endl;
//return the stream. cout print the stream result.
return out;
}
Only you also have at first to declare the operator in the same namespace where the class is defined.
If you want that the operator would be declared in the global namespace then you can do it the following way
namespace biumath
{
class Assignment;
}
std::ostream& operator<< ( std::ostream &,
const biumath::Assignment & );
namespace biumath
{
class Assignment
{
//...
friend std::ostream& ::operator<< (std::ostream& out,
const Assignment& assignment);
};
}
You've befriended an operator in your biumath namespace, but you don't define that; instead you define a separate operator in the global namespace.
Re-open the namespace in the source file, and put the definition inside it.
Would anyone mind helping me with a C++ linking/coding conundrum?
I have a class Shape. Shape needs to use class Center's private data members, x and y coordinates. I declare friend class Shape; and then #include "center.h" in Shape.h. In Shape.cpp, I define my ostream& operator<< (ostream& ostr, const Center& c) function, which uses c.xCord; c.yCord to access Center's private data members.
When I attempt to compile Shape.cpp I get access errors for those data variables like I haven't declared Shape as a friend class. I have a feeling this has something to do with the linking order at compile time. How can I fix this?
#ifndef CENTER_H
#define CENTER_H
class Center
{
public:
Center(double x, double y) { xCord = x; yCord = y; }
// constructor
friend class Shape;
// allow Shape to use Center's x and y values
private:
double xCord;
// X-coordinate
double yCord;
// Y-coordinate
};
#endif
#ifndef SHAPE_H
#define SHAPE_H
#include "center.h"
#include <iostream>
using namespace std;
class Shape
{
public:
Shape(double x, double y) : s_center(x, y) {}
// constructor
void moveCenter();
// moves the center of the shape
friend ostream& operator<< (ostream& ostr, const Center& c);
// allows the printing of the Center object
virtual void printCenter();
// returns the center of the shape
virtual double printArea();
// returns the area of the shape
virtual bool checkSurface(Shape& s) = 0;
// checks if the shape can fit into
// a given surface
virtual double findArea() = 0;
// calculates the area of the shape
private:
Center s_center;
// center of the shape
};
#endif
// in shape.cpp
ostream& operator<< (ostream& ostr, const Center& c)
{
ostr << "(" << c.xCord << ", " << c.yCord << ")";
return ostr;
}
Per Paragraph 11.3/10 of the C++11 Standard:
Friendship is neither inherited nor transitive. [...]
If class A is a friend of class B, and function f() is a friend of class A, this does not make f() a friend of class B as well.
You should declare your operator << as friend of class Center if you want it to access private member variables of Center:
#ifndef CENTER_H
#define CENTER_H
#include <ostream>
class Center
{
public:
Center(double x, double y) { xCord = x; yCord = y; }
friend class Shape;
friend std::ostream& operator<< (std::ostream& ostr, const Center& c);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
private:
double xCord;
double yCord;
};
#endif
Your operator << has nothing to do with class Shape. The friendship does not extend to the operator. You need to declare that specific operator as a friend.
Problem Solved, thank you all for your help!
I've run into a problem that i can't seem to figure out.
I am trying to overload the ostream operator as a friend function in order to be able to print out the member data of that object, and i can't seem to get it to work.
This is what i got so far:
.h file:
Class TestIt:
{
public:
TestIt();
TestIt(int a, b);
friend ostream& operator <<(ostream& outputStream, const TestIt& a);
Private:
int NUMBER1;
int NUMBER2;
};
.cpp file:
ostream& operator <<(ostream& outputStream, const TestIt& a)
{
outputStream << a.NUMBER1 << " " << a.NUMBER2;
return(outputStream);
}
What i am trying to do is, pass in an object in ostream, then output its member data.
The error that i am receiving is that
"the member TestIt::NUMBER1 declared in TestIt.h is inaccessible.
and same error also exists with my other member data.
Why would that be?
Thank you for your help.
Here's a whole program that i just wrote, giving me the same error:
TestClass.cpp
#include "TestClass.h"
#include <iostream>
using namespace std;
TestClass::TestClass(int a, int b)
{
age = a;
whole = b;
}
int TestClass::GetAge() const
{
return(age);
}
ostream& operator <<(ostream& outputStream, const TestClass& t1)
{
t1.whole;
t1.age;
return(outputStream);
}
TestClass.h
#ifndef TestClass_H
#define TestClass_H
class TestClass
{
public:
TestClass(int a, int b);
int GetAge() const;
friend ostream& operator <<(ostream& outputStream, const TestClass& t1);
private:
int whole;
int age;
#endif
The operator<< that you've defined and the operator<< that you've friended aren't the same name. Are you using namespaces?
What do these errors mean?
Vector.cpp:13: error: ISO C++ forbids declaration of ‘Vector’ with no type
Vector.cpp:13: error: explicit qualification in declaration of ‘void Vector::Vector(double, double, double)’
The C++ (Line 13 is the Vector::Vector( ...):
#include <iostream>
using namespace std;
namespace Vector
{
Vector::Vector( double x, double y, double z)
{
a = x;
b = y;
c = z;
}
/*
double Vector::dot(const Vector &v) const
{
return (a*v.a)+(b*v.b)+(c*v.c);
}
*/
Vector Vector::operator+(const Vector &v) const
{
Vector v1( a + v.a, b + v.b, c + v.c );
return v1;
}
Vector Vector::operator-(const Vector &v) const
{
Vector v1( a - v.a, b - v.b, c - v.c );
return v1;
}
bool Vector::operator==(const Vector &v) const
{
if( (a == v.a) && (b == v.b) && (c == v.c) )
{
return true;
}
else
{
return false;
}
}
Vector Vector::operator*(const Vector &v) const
{
Vector v1( b*v.c - c*v.b, c*v.a - a*v.c, a*v.b - b*v.a );
return v1;
}
ostream& operator<<(ostream &out, const Vector &v)
{
out << "<" << v.a << ", " << v.b << ", " << v.c << ">";
return out;
}
istream& operator>>(istream &in, Vector &v)
{
in >> v.a;
in >> v.b;
in >> v.c;
return in;
}
/*
double length( Vector v )
{
return sqrt( (v.a*v.a)+(v.b*v.b)+(v.c*v.c) );
}
*/
} // end namespace Vector
The header file:
#ifndef _VECTOR_H
#define _VECTOR_H
#include <cstdlib>
#include <iostream>
using namespace std;
namespace Vector
{
class Vector
{
private:
double a;
double b;
double c;
public:
Vector( double x=0.0, double y=0.0, double z=0.0);
double dot(const Vector &v) const;
Vector operator+(const Vector &v) const;
Vector operator-(const Vector &v) const;
bool operator==(const Vector &v) const;
Vector operator*(const Vector &v) const;
friend ostream& operator<<(ostream &out, const Vector &v);
friend istream& operator>>(istream &in, Vector &v);
}; // end Vector class
double length(Vector v);
} //end namespace Vector
#endif /* _VECTOR_H */
Constructors have no return type, not even void. Just remove the void and you're fine.
Looks like the major problem is that your cpp files didn't include your header file.
Include the header file in the cpp file. Also, the code has some design issues. operator+ should return const Vector and the same case with operator-.