1
votes

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;
}
2
Why would operator<<(ostream&,const Center&) be a friend of Shape? - David Rodríguez - dribeas
Good point. I've moved it into the Center class. Thanks for pointing that out. - Taylor

2 Answers

4
votes

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
1
votes

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.