Как определить оператор Friend << для частного члена класса в файле .cpp, а не в заголовке? - PullRequest
0 голосов
/ 23 апреля 2019

Сбой компиляции этого кода:

class P {
//public:
  class C {
  friend std::ostream& operator<<(std::ostream &os, const C &c);
  };
};


std::ostream& operator<<(std::ostream &os, const P::C &c) {
  return os;
}

ошибка:

test.cpp:12:53: error: 'C' is a private member of 'P'
std::ostream& operator<<(std::ostream &os, const P::C &c) {
                                                    ^
test.cpp:6:9: note: implicitly declared private here
  class C {
        ^
1 error generated.

Раскомментирование public: делает этот код для компиляции. И, очевидно, его можно перенести в сам класс.

Но как правильно определить такое operator<< в файле cpp для закрытого члена класса?

1 Ответ

3 голосов
/ 23 апреля 2019

Чтобы увидеть приватные элементы P, ваш operator<< должен быть другом P. Таким образом, чтобы иметь возможность получить доступ к определению класса C:

class P {
  class C {
      ...
  };
  friend std::ostream& operator<<(std::ostream &os, const C &c);
};

Затем ваш текущий оператор скомпилирует. Но он может получить доступ только к открытым членам C, так как он является другом вложенного P, но не вложенного C:

std::ostream& operator<<(std::ostream &os, const P::C &c) {
  return os;
}

Если вам также нужен доступ к закрытым членам C, вам нужно быть двойным другом:

class P {
  class C {
    int x;   //private 
    friend std::ostream& operator<<(std::ostream &os, const C &c);  // to access private x
  };
  friend std::ostream& operator<<(std::ostream &os, const C &c); // to access private C
};

std::ostream& operator<<(std::ostream &os, const P::C &c) {
  os<<c.x; 
  return os;
}
...