0

I am writing a C++ program where I wish to use a friend class in order to access protected members of another class. Here is the header for the class I wish to access:

#pragma once

#include <vector>

#include "../glm/glm.hpp"

// An enum class and some structs here

class Polygon {
public:
    // Constructors, destructor...
    Polygon();
    Polygon(int n_vertices, int n_indices);
    Polygon(int n_vertices, int n_indices, float* vertices, unsigned int* indices);
    ~Polygon();
    
    // Loads of other irrelevant functions go here
    
protected:
    // Bunches of other ivars before these
    unsigned int lastVBO;
    unsigned int lastVAO;
    unsigned int lastIBO;
    
    friend class Renderer;
};

And here is the declaration of the class which I wish to be its friend:

#include <string>
#include <iostream>
#include <vector>

#include "../geometry/polygon.hpp"
#include "../geometry/rectangle.hpp"
#include "../geometry/circle.hpp"

class Renderer {
public:
    Renderer();
    ~Renderer();
    void queuePolygon(Polygon* p);
    void drawPolygons();
private:
    // Rectangle and Circle are children of Polygon
    // Which one of these gets called is determined in queuePolygon/drawPolygon
    void queueRectangle(Rectangle* r);
    void queueCircle(Circle* c);
    void drawRectangle(Rectangle* r);
    void drawCircle(Circle* c);
    
    std::vector<Rectangle*>* rectangleQueue;
    std::vector<Circle*>* circleQueue;
};

Now obviously what I want is to get access to the protected members IBO, VBO and VAO from the Polygon class, in order to draw that polygon using my renderer. Yet with this implementation, I don't have access to those ivars even with the friend declaration in the Polygon class. Importing the renderer header in polygon.hpp breaks the entire thing as subclasses no longer behave nicely.

Has anyone encountered this problem before, and can you tell me what I am doing wrong?

Henrik Hillestad Løvold
  • 1,213
  • 4
  • 20
  • 46
  • 2
    First view result: Wrong design! If I see a "renderer" which provides separate methods for "rectangle, circle... " it looks wrong to me. A typical design should end up in splitting the "what" ( circle, rectangle ) and the "how", implemented in a set of render implementations. That you have to expose ( via friend, getters or public data ) internal data of objects is a bad idea. – Klaus Apr 29 '22 at 07:58
  • 1
    You should probably clarify exactly what you mean by `"... breaks the entire thing as subclasses no longer behave nicely"`. What errors/symptoms do you see? – G.M. Apr 29 '22 at 07:58
  • Thank you @Klaus, I've recently started to implement the header. In the "prototype", drawing was handled internally in the Polygon class, which I wish to rectify. I might have to redesign. – Henrik Hillestad Løvold Apr 29 '22 at 08:03
  • @G.M. the subclasses no longer recognise Polygon as a base class. – Henrik Hillestad Løvold Apr 29 '22 at 08:03
  • Not sure I completely understand the last comment but it sounds like the real problem may be [circular dependencies](https://stackoverflow.com/questions/625799/resolve-build-errors-due-to-circular-dependency-amongst-classes) amongst your classes. – G.M. Apr 29 '22 at 08:25
  • I removed the buffer fields from the Polygon class as frankly, they don't belong there when I have a renderer. Moved it to the renderer, dropped the friend class thingy, and now things are both working and more tidy. – Henrik Hillestad Løvold Apr 29 '22 at 09:01

0 Answers0