Дружественные методы в C++

Почему в C++ следующий код не будет работать? Неужели на это есть веские причины?

    #include <iostream>

    // предварительное объявление класса - нужно, чтобы компилятор не ругался
    // на объявление friend в конце класса Values
    class Display;

    class Values
    {
    private:
        int m_intValue;
        double m_dValue;
    public:
        Values(int intValue, double dValue) : m_intValue {intValue}, m_dValue {dValue} { }
        // ошибка: Values не видит полного определения класса Display
        // а зачем ему полное определение?..
        friend void Display::displayItem(Values& value);
    };

    class Display
    {
    private:
        bool m_displayIntFirst;
    public:
        Display(bool displayIntFirst) : m_displayIntFirst {displayIntFirst} { }
        void displayItem(Values &value)
        {
            if (m_displayIntFirst)
            {
                std::cout << value.m_intValue << " " << value.m_dValue << std::endl;
            }
            else
            {
                std::cout << value.m_dValue << " " << value.m_intValue << std::endl;
            }
        }
    };

И в итоге, чтобы сделать то, что планировалось, нужно поменять местами классы, написать предварительное объявление класса Values и определение метода displayItem вынести за пределы класса.

    #include <iostream>

    class Values;

    class Display
    {
    private:
        bool m_displayIntFirst;
    public:
        Display(bool displayIntFirst) : m_displayIntFirst {displayIntFirst} { }
        // предварительное объявление, приведённое выше, нужно для этой строки
        void displayItem(Values &value);
    };

    class Values
    {
    private:
        int m_intValue;
        double m_dValue;
    public:
        Values(int intValue, double dValue) : m_intValue {intValue}, m_dValue {dValue} { }
        friend void Display::displayItem(Values& value);
    };

    void Display::displayItem(Values &value)
    {
        if (m_displayIntFirst)
        {
            std::cout << value.m_intValue << " " << value.m_dValue << std::endl;
        }
        else
        {
            std::cout << value.m_dValue << " " << value.m_intValue << std::endl;
        }
    }

Только теперь всё будет работать правильно. Я хотел спросить - не исправили ли это в новых версиях C++? И да, я понимаю, что этой ошибки можно легко избежать, просто делая многофайловый проект, а не пихая всё в один файл. Но иногда очень хочется однофайловый :)


Ответы (0 шт):