Почему для понятия класса друзей не требуется объявление вперед?

Я только недавно узнал о класс другав C++ (я немного погуглил, но этот ответзаставил меня смеяться, пока я не вспомнил самые важные части), и я пытаюсь включить его в к проекту, над которым я сейчас работаю. Конкретный вопрос выделен в конце, но вообще меня смущает полное отсутствие предварительных объявленийв моем рабочем коде.

Все мои классы разделены (под)папками и каждый в отдельный файл .hи .cpp, но этого должно быть достаточно, чтобы получить представление о зависимости:

// FE.h - no implementations - no .cpp file
class FE
{
    private:
       virtual void somePrivateFunc() = 0;
    // 90% virtual class, interface for further implementations
    friend class TLS;
};

// DummyFE.h
#include "FE.h"
class DummyFE :: public FE {
    /* singleton dummy */
    private:
        // constructor
    public:
        static DummyFE& instance();
};
// DummyFE.cpp
#include "DummyFE.h"
// all Dummy FE implementation

// ImplFE.h
#include "FE.h"
class ImplFE :: public FE { /* implemented */ };
// ImplFE.cpp
#include "FE.cpp"
// all Impl FE implementations


// SD.h - implements strategy design pattern
//        (real project has more than just FE class in here)
#include "FE.h"
#include "DummyFE.h"
class SD
{
    private:
        FE &localFE;
    public:
        SD(FE ¶mFE = DummyFE::instance());
    // ... and all the other phun stuff ... 
    friend class TLS;
};
// SD.cpp - implementations
# include "SD.h"
/* SD implemented */

// TLS.h - implements strategy design pattern
           (on a higher level)
#include SD.h
class TLS{
    private:
        SD *subStrategy;
    public:
        void someFunctionRequiringFriendliness();
}

// TLS.cpp - implementations
#include "TLS.h"
void TLS::someFunctionRequiringFriendliness(){
    this->subStrategy->localFE.somePrivateFunc(); // ok!
}

Теперь у меня была партия, чтобы все это действительно скомпилировалось со всеми зависимостями (пришлось записать это в диаграмму классов в конце, чтобы заставить это работать), но теперь это работает. Тот факт, что на самом деле меня смущает, заключается в том, что никаких предварительных объявлений не требовалось. Я знаю о форвардных объявлениях раньше, и на всякий случай освежил свою память этим ответом.

Итак, чтобы внести ясность, мой вопрос: Почему при объявлении класса TLSдругом не потребовалось явных предварительных объявлений? Означает ли это, что объявление дружественного классаявляется предварительным объявлением само по себе? Для меня интуитивно чего-то здесь не хватает... А так как компилируется и работает нормально, может кто поможет поправить мою интуицию? :D

PS извините за такое длинное введение в вопрос и кучу кода. Пожалуйста, не комментируйте мою концепцию кода - друзья здесь хороши, я почти уверен, что это правильно для моего текущего проекта (просто немного трудно увидеть из этого скелета). Я просто хотел бы знать, почему нигде не понадобилось предварительное объявление.

11
задан Community 23 May 2017 в 12:34
поделиться