被通缉的朋友功能包括

pby*_*ian 5 c++ circular-dependency friend include

Class A是class实例的唯一实例化器和容器B

因此,将类的构造函数设为B私有,并且仅通过在class中声明并在class中B定义的朋友函数来调用它似乎是一个好主意A

文件Ah(编辑:包含在类B中定义的枚举)

#ifndef   A_H
#define   A_H

#include "B.h"

using namespace std;

class A
{   public:
    A();
    shared_ptr<B> CreateBInstance( const B::ENUM_STANDARD_COLORS );
    shared_ptr<B> CreateBInstance( const string );  // Custom color

    private:
    unique_ptr<map<int, shared_ptr<B>>> UPTR__BInstancesMap;
}
#endif
Run Code Online (Sandbox Code Playgroud)

文件Bh(编辑:包含在类B中定义的枚举)

#ifndef   B_H
#define   B_H

#include "A.h"  // Causes chaos

using namespace std;

class B
{   public:
    enum class ENUM_STANDARD_COLORS : unsigned int
    {   ...     // ~70 standard colors
    };

    private:
    B();

    friend
    shared_ptr<B> A::CreateBInstance( const ENUM_STANDARD_COLORS );

    friend
    shared_ptr<B> A::CreateBInstance( const string );   // Custom color
}
#endif
Run Code Online (Sandbox Code Playgroud)

A需要类的完整声明(#包括)Bshared_ptr<B>

B需要A对friend函数进行一些类声明。一个简单的前向声明会导致错误:

无效使用不完整类型“结构A”

在朋友函数声明中。

完整的声明(#include)要糟糕得多:

错误:“ std :: shared_ptr A :: CreateInstance()”的原型与类“ A”中的任何内容都不匹配

(但确实如此!)在朋友函数声明中。
并且,因为B现在类已损坏:

错误:未在此范围内声明“ B”
错误:模板参数1无效

出现在B班级中的每一次提及中A,以及出现在#include类中供自己使用的班级FG(等)Bshared_ptr<B>
而且,由于class FG现在也被破坏了:

错误:此作用域中未声明'F'
错误:模板参数1无效>
错误:此作用域中未声明'G'
错误:模板参数1无效

出现在每一个提到FG在课堂上A

不幸的是,include防护不会阻止循环包含。

有没有办法使这个朋友功能起作用?我从来没有一次犯下这么多错误!

son*_*yao 5

A需要类的完整声明(#包括)Bshared_ptr<B>

不,在中的向前声明就足够了A.hshared_ptr(and unique_ptr)不需要类B是返回类型声明[1]和类数据成员声明的完整类型。

文件啊

#ifndef   A_H
#define   A_H

class B;  // forward declaration

using namespace std;

class A
{   public:
    A();
    shared_ptr<B> CreateBInstance();

    private:
    unique_ptr<map<int, shared_ptr<B>>> UPTR__BInstancesMap;
};
#endif
Run Code Online (Sandbox Code Playgroud)

[1]对于不是的“常规”类型T也是如此shared_ptr

  • @pbyhistorian您应该在A.cpp中使用#include Bh,但不要在Ah中使用。 (2认同)