Search code examples
c++classfriendmember-functions

Why can't I make this member function friend of another class?


#ifndef BUTTONS_H
#define BUTTONS_H

class Window;

class Buttons
{
  friend int main();
  friend void Window::setCloseButtonCaption(string);

public:
    Buttons();
    Buttons(string, Window&);
    ~Buttons();

    void setCaption(string);
    string getCaption();

private:
    string caption;
    const Window * parentWindow;
};

class Window
{

public:
    Window();
    Window(int i, int l,int t, int w, int h, Buttons& B): id(i),left(l), top(t), width(w), height(h), closeButton(B){}
   ~Window(void);

    void setleft(int);
    void settop(int);
    void setw(int);
    void seth(int);

    int getid() const;
    int getleft() const;
    int getwidth() const;
    int getheight() const;
    int getnW() const;

    void Print() const;
    void setCloseButtonCaption(string);

private:
    const int id;
    int left;
    int top;
    int width;
    int height;
    static int numberOfWindows;
    const Buttons closeButton;
};

#endif

The code ran fine until I made the function Window::setCloseButtonCaption(string) a friend of the Buttons class. I tried defining the class Window before the class Buttons but it didn't change. It gave me the errors:

-use of undefined type 'Window'

-see declaration of 'Window'

I'm a beginner by the way, it would be very helpful to provide a detailed explanation. Thanks a lot


Solution

  • For class members (unlike free functions) member declaration should be visible before friend declaration.

    I would normally suggest to define your Window class before Buttons class to be able to befriend it's members. However, your Window class needs defined Buttons. So, you have possible solutions:

    • Switch to using Buttons by pointer or reference in Window
    • You can make Buttons an inner struct to the Window. Something like that (abridged code)

    ...

    struct Window {
      void setCloseButtonCaption(const std::string& caption);
      struct Buttons {
          friend void Window::setCloseButtonCaption(string);
      };
      Window(int i, int l,int t, int w, int h, Buttons& B): id(i),left(l), top(t), width(w), height(h), closeButton(B){}
    };