鉴于一个类及其朋友类,后者的内部类是否自动成为前一类的朋友?

时间:2012-03-27 18:29:53

标签: c++ friend nested-class

我正在尝试使用开源项目。最新官方(来自* .tar.gz文件)和前沿(来自SVN存储库)版本的内容如下:

class Type1 {
    friend class Ridiculous;
    friend class Number;
    friend class Of_Friends;

    int  ImportantPrivateSemiSharedData;
};

 // In another header...

class Ridiculous {
    class Inner {
        void  MyFunc( Type1 &t )
        { /*do something with t.ImportantPrivateSemiSharedData*/ }
    };
};

AFAIK,将class A标记为friend class B会提供与A friend发货权相关联的任何类型与B。从[{1}}派生的类和A friend A的{​​{1}}类friend都不会附带B。我认为这种限制也适用于内部类。

我正在使用2002年的一台计算机卡住了几个操作系统版本,而该程序(可能是它的设计团队)主要是在新的计算机上。我的系统编译器是旧的和破坏的,还是新热点的编译器允许他们不应该做的事情?这是C ++ 11的变化吗?

我只是想使用这个程序,但我一直陷入这样的困境。我已经怀疑了,因为代码中充满了各种各样的技术,比如“拥有大量朋友的私人数据”和“无处不在的内部类”,我认为这些代码气味。团队正在一起使用这些技术,但我认为它们基本上是不兼容的,因为friend船没有结转,你不能前向声明内部类。

(如果需要,我使用的是Mac OS X Tiger 10.4.11 / PowerPC 32位(配备G4的eMac)。该程序是LLVM和CLang(以及LLVM测试套件),试用v3来自Subversion的.0档案和r153311。编译器是Apple提供的带XCode 2.5的GCC 4.0.1。)

附录

看到第一个回复,现在我怀疑将一个班级标记为朋友有两种解释。如果class A中包含friend class X,则该声明可以授予对以下内容的访问权:

  1. static
  2. 的成员函数(X或特殊或两者都没有)
  3. 任何函数,包括特殊函数,其完全限定名称具有 完全限定名称X作为前缀。
  4. 我认为我的编译器使用第一个定义,而编写器的编译器使用第二个定义。是否有正式的解释是正确的?如果是这样,规范何时发生(C ++ 98/03,缺陷报告,C ++ 11)?我一直认为友谊意味着第一个版本(包括我读过的C ++材料);直到现在,第二个从未进入我的脑海。

1 个答案:

答案 0 :(得分:1)

我认为这里有两个问题。一个是代码闻起来很糟糕,正如你所说,第二个是它不能在你的系统上编译。关于气味,是的,过度使用friend关键字通常表示不良的OO设计。通常情况下,给对象提供完成工作所需的内容而不是从中提取一些东西,这实际上就是friend允许你做的事情。

大量的内部类,IMO,并不是那么糟糕,因为它们只是用于将类保持在另一个类的范围内。这有助于保持命名空间不那么混乱,并允许您在不同的功能区域中使用通用名称。

关于编译问题,我试图在我的系统上重现这个问题(Ubuntu 10.04,gcc 4.4.3,此时已有两年了),并创建了这个示例程序:

class A
{
    friend class B;

    int x;
};

class B
{
    class Inner
    {
    public:
        void foo(A& a)
        {
            a.x++;
        }
    };

public:
    void bbb()
    {
        Inner i;
        A a;

        i.foo(a);
    }
};

int main()
{
    B b;

    b.bbb();
}

编译时没有错误或警告。我最初没有标记为public,但我需要添加bbb()来创建类Inner的实例,我必须添加Inner的公共方法,以便我可以调用它来执行有A的东西。

结果是我认为你的开发系统已经过时了。主要的开发人员显然没有编译代码的问题,因此差异必须与您的系统有关,否则他们已经以他们没有告诉您的方式配置他们的系统。话虽这么说,我认为他们可以做更多的事情来使他们的代码更便携,更容易构建。在开源项目中,如果您希望其他人贡献,那就是预期的。