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