Где разместить определение не-членской функции ЧАСТНОГО вложенного (внутреннего) класса? - PullRequest
0 голосов
/ 05 февраля 2019

Ниже приведен простой пример моей настоящей проблемы.У меня есть функция, не являющаяся членом, определенная с помощью ключевого слова friend в InnerClass.Определение этой функции должно быть за пределами InnerClass.

С другой стороны, определение класса находится под private из MyClass, так как я хочу использовать InnerClass специально для MyClass.

В этом случае , где я могу поместить определение функции friend?

#include <iostream>

class MyClass
{
private:
    class InnerClass
    {
        int m_int;
    public:
        InnerClass(int i) :m_int(i) {}

        // non-member (friend) function, for which I need a definition outside the class!
        friend std::ostream& operator<<(std::ostream& output, const InnerClass &obj);
    };
    // ERROR: too many parameter for this operator
    std::ostream& operator<<(std::ostream& output, const InnerClass &obj)
    {
        return output << obj.m_int << " ";
    }

private:
    InnerClass m_innerClass;

public:
    explicit MyClass(int i) : m_innerClass{ i } {}
    friend std::ostream& operator<<(std::ostream& output, const MyClass &obj);
};

std::ostream& operator<<(std::ostream& output, const MyClass &obj)
{
    output << obj.m_innerClass << std::endl;
}


int main()
{
    MyClass classObj{ 2 };
    std::cout << classObj;
    return 0;
}

Сообщение об ошибке:

  \main.cpp(27): error C2804: binary 'operator <<' has too many parameters
  \main.cpp(27): error C2333: 'MyClass::operator <<': error in function declaration; skipping function body

1 Ответ

0 голосов
/ 05 февраля 2019

Вы можете фактически определить функции, не являющиеся членами-друзьями, прямо внутри определения класса.

Вот ваш исправленный фрагмент кода:

#include <iostream>

class MyClass
{
private:
    class InnerClass
    {
        int m_int;
    public:
        InnerClass(int i) :m_int(i) {}

        // non-member (friend) function, which we can define right here
        friend std::ostream& operator<<(std::ostream& output, const InnerClass &obj)
        {
            return output << obj.m_int << " ";
        }
    };    

private:
    InnerClass m_innerClass;

public:
    explicit MyClass(int i) : m_innerClass{ i } {}
    friend std::ostream& operator<<(std::ostream& output, const MyClass &obj);
};

std::ostream& operator<<(std::ostream& output, const MyClass &obj)
{
   return output << obj.m_innerClass << std::endl;
}


int main()
{
    MyClass classObj{ 2 };
    std::cout << classObj;
    return 0;
}

Вы можете сделать то же самое с другими operator<<.

Теперь, если InnerClass не является частным, вы все равно можете определить функцию в глобальной области видимости, но вам необходимо полностью указать имя второго параметра:

std::ostream& operator<<(std::ostream& output, const MyClass::InnerClass &obj)
{                                                //  ^^^^^^^^^^^^^^^^^^^ 
    return output << obj.m_int << " ";
}
...