朋友类概念不需要如何申报?

pen*_*ope 11 c++ class forward-declaration friend-class

我刚刚学会了friend classC++中的概念(我已经搜索了一下,但这个答案让我笑到我记得最重要的部分),而我正试图把它融入项目中我是现在正在努力.这个简明的问题最终被挑出来了,但总的来说,我对我工作代码中完全缺乏前向声明感到困惑.

我的所有类都通过(子)文件夹分隔,每个文件夹分别放在一个单独的.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 &paramFE = 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!
}
Run Code Online (Sandbox Code Playgroud)

现在,我已经让派对将所有这些实际编译为所有依赖项(必须将其写入到最终的类图中以使其工作),但现在它确实如此.实际上令我困惑的事实是,不需要前瞻性声明.我知道前面的前向声明,为了以防万一,我用这个答案刷新了我的记忆.

所以,为了保持清楚,我的问题是:当宣布class TLS作为朋友时,为什么不需要明确的前瞻性声明?这是否意味着friend class宣言是一个自我的前瞻声明?对我来说,直觉上,这里缺少的东西......由于它编译和正常工作,有人可以帮助纠正我的直觉吗?:d

PS抱歉这么长的问题和一堆代码的介绍.请不要评论我的代码概念 - 朋友们在这里很好,我很确定这对我当前的项目来说是正确的(从这个骨架中看起来有点难度).我想知道为什么在任何地方都不需要前方声明.

Dav*_*eas 7

friend class TLS;
Run Code Online (Sandbox Code Playgroud)

这种语法本身就是一个声明,这就是为什么你不需要额外的先前声明的类型.请注意,friend声明与封闭命名空间中的声明略有不同(特别是对于函数).

特别是,除非在封闭命名空间中也有声明,否则声明中声明的函数friend只能通过参数依赖查找找到(并且不能在类之外定义).对于类来说也是如此,除非在命名空间级别也有声明,所以声明的类型在类之外不可用,并将其声明为朋友.

class B {
   friend class A;
};
//A foo();    // Error: A is not declared here!
class A;
A foo();      // Fine
Run Code Online (Sandbox Code Playgroud)


Luc*_*ore 6

你是对的,朋友声明有点像前瞻声明.

以下编译:

class A;
class B
{
   friend A;
};
Run Code Online (Sandbox Code Playgroud)

要么

class B
{
   friend class A;
};
Run Code Online (Sandbox Code Playgroud)

这不是:

class B
{
   friend A;
};
Run Code Online (Sandbox Code Playgroud)

它实际上并不是friend前向声明的声明class A,而是class关键字.这就是为什么第二个例子不起作用,因为它不知道是什么A.如果您A事先声明,就像在第一个片段中一样,它可以解析A为类声明.

我纠正了.