为什么在课堂内不需要"使用前声明"规则?

peo*_*oro 12 c++ class forward-declaration

我想知道为什么C++的declare-before-use规则不能保存在类中.

看看这个例子:

#ifdef BASE
struct Base {
#endif
    struct B;
    struct A {
        B *b;
        A(){ b->foo(); }
    };

    struct B {
        void foo() {}
    };
#ifdef BASE
};
#endif

int main( ) { return 0; }
Run Code Online (Sandbox Code Playgroud)

如果定义了BASE,则代码有效.

在A的构造函数中,我可以使用尚未声明的B :: foo.

为什么这有效,而且大多数情况下,为什么只能课堂上工作?

Sve*_*ach 8

这是因为只有在编译器解析了整个类定义之后才编译成员函数,即使函数定义是内联编写的,而常规函数在读取后立即编译.C++标准需要这种行为.

  • @Blindy:嗯?你不能?你*可以*实际上.您*可以*从该类中声明的成员函数返回该类的实例. (3认同)

AnT*_*AnT 7

好吧,要迂腐,C++中没有"使用前声明规则".存在名称查找规则,这些规则非常复杂,但可以(并且经常)大致简化为通用的"使用前声明规则",但有许多例外.(在某种程度上,情况类似于"运算符优先级和关联性"规则.虽然语言规范没有这样的概念,但我们经常在实践中使用它们,即使它们并不完全准确.)

这实际上是其中一个例外.C++中的成员函数定义被明确地和有意地排除在"使用前声明规则"之外,从某种意义上说,这些成员的主体的名称查找就像在类定义之后定义一样.

语言规范指出在3.4.1/8(和脚注30)中,尽管它使用了不同的措辞.它表示在从成员函数定义进行名称查找期间,将检查整个类定义,而不仅仅是成员函数定义上方的部分.脚注30另外说明了查找规则对于类定义内部或类定义之外定义的函数是相同的(这与我上面所说的几乎相同).

你的例子有点不重要.它提出了关于嵌套类中成员函数定义的直接问题:它们是否应该被解释为它们是在最封闭类的定义之后定义的?答案是肯定的.3.4.1/8也涵盖了这种情况.

"C++的设计和演变"一书描述了这些决策背后的原因.