-1

My code:

class Controller {

private:
    class ControllerMetals {
        private:
            int m_size;
            Metals * m_metals;
        public:
            ControllerMetals();
            Metals & getMetals() const;
            int getSize() const;
            void setSize(int size) { m_size = size; }
            void init();
            void show();
            void erase();
        friend void Controller::start(ControllerMetals & c); // why don't work ?
    };

private:
     ControllerMetals * controlMetals;

public:
    void start(ControllerMetals & c);
    ControllerMetals * getControlMetals() const;
    Controller();

};

I want to make a void start to have access private member in ControllerMetals class. Why friend statements don't work ?

loczek
  • 123
  • 1
  • 6
  • 1
    Since ControllerMetals is private inside of Controller, why not make everything public in ControllerMetals? Obviously the nested private class is tightly coupled with the outer class. – Eljay Nov 22 '18 at 22:25
  • I have a task and I must declare my inner class as private member of outer class. And all member must be private. – loczek Nov 22 '18 at 22:56
  • `Controller::start` doesn't exist when you friend it. You can declare a datatype when you friend it but I don't think you can with a function. Forward declare `ControllerMetals` so you can refer to it and then formally define it after the functions. Why the hell didn't I just make an answer? – user4581301 Nov 23 '18 at 01:48

1 Answers1

2

Problem

Member functions have to be declared before you can friend them. friend has a built-in forward declaration for a data type, but not for members of that data type.

Solution

Personally I agree with Eljay's comment, make everything in ControllerMetals public because it is already hidden by Controller, but if the assignment says no, do what you have to do to pass the course.

Simple solution:

You friend the whole Controller class to get the members, but this might be too broad.

More complicated, tighter-grained solution:

More stuff around so that the required member function is declared before ControllerMetals. You can get away with this because the start only needs a declaration of ControllerMetals in order to take references to it.

class Controller {

    class ControllerMetals; // forward declare to make available for referencing
public:
    void start(ControllerMetals & c); // start now known. Can friend
    ControllerMetals * getControlMetals() const;
    Controller();

private:
    // now we can fully define ControllerMetals
    class ControllerMetals {
        private:
            int m_size;
            Metals * m_metals;
        public:
            ControllerMetals();
            Metals & getMetals() const;
            int getSize() const;
            void setSize(int size) { m_size = size; }
            void init(); // why is this not done in the constructor?
            void show();
            void erase();
        friend void Controller::start(ControllerMetals & c); // now works
    };
     ControllerMetals * controlMetals;


};
Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54