Search code examples
c++classnestedfriend

C++ Nested class (Make friend outer member function)?


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 ?


Solution

  • 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;
    
    
    };