把他们的声明上述功能(calling functions above their declarati

2019-07-30 19:55发布

void foo()
{
    bar();          // error: ‘bar’ has not been declared
}

void bar()
{
}

namespace N
{
    void foo()
    {
        N::bar();   // error: ‘bar’ is not a member of ‘N’
    }

    void bar()
    {
    }
}

class C
{
    static void foo()
    {
        C::bar();   // works just fine
    }

    static void bar()
    {
    }
};

这是什么矛盾来处理其声明上述函数的调用背后的原理是什么? 为什么我能做到一个类里面,而不是内部的命名空间或在全局范围内?

Answer 1:

您可以定义成员函数或者类中,或之后类的声明,或一些每个。

为了在这里得到一定的一致性,对于联定义函数的类的规则是,它仍然有仿佛职能级定义进行编译。

您的代码

class C {
     static void foo()
     {
         C::bar();   // works just fine 
     }

     static void bar()
     {     }
 }; 

编译一样

class C {
     static void foo();
     static void bar();
 }; 

 void C::foo()
 {  C::bar();  }

 void C::bar()
 {     }

现在存在的知名度没有魔法,因为这些功能都可以看到在类中声明的一切。



Answer 2:

  1. 命名空间可以重新开放,新的东西可以在任何地方进行添加。 类不能被重新打开 - 所有的内容必须在一个地方放。

  2. 函数原型是合法的命名空间,但不是按类别。

你可以写

namespace n
{
    void foo();

    void bar()
    {
        foo();
    }

    void foo()
    {
    }
}

但不是

class C
{
    void foo();

    void bar()
    {
        foo();
    }

    void foo()
    {
    }
}

因此,类需要这样的功能,更多的,它是更容易实现为他们比命名空间。



Answer 3:

嗯,也许因为你在一个地方类声明,编译器可以很容易地获得它的成员的信息。

命名空间,而另一方面,可以有它的吨不同的文件的东西,你不能指望编译器通过他们看,因为它不知道去哪里找摆在首位。

为了避免这种情况,只需使用函数原型 。



Answer 4:

我不知道,但我的想法是,一class是有些对象 (使用不当),其中所有的内部组件协同工作(一般来说),其成员将肯定需要它的方法。

但是,一个命名空间是不同的,功能都没有关系。 这意味着,一个功能心不是打算与命名空间内的所有其他职能工作。

因此分裂声明和定义是你能做的最好的事情。

如果foo()需要bar()其最有可能会在同一个声明文件,并且将工作方式



Answer 5:

请参阅下面的报价从标准

3.3.7类范围[basic.scope.class]

1)下列规则描述了在类中声明的名称的范围。 1)在一个类中声明的名称的潜在范围不仅包括以下声明的名称的点声明地区,但所有函数体,默认参数,并且在非静态数据成员的大括号或-equalinitializers也类(包括嵌套类这样的事情)。

2)在一个S类使用应指在其上下文相同的声明和当A名称为N在没有诊断需要一个该规则的冲突S的完成范围重新评估。

typedef int c;
enum { i = 1 };

class X {
     char v[i]; // error: i refers to ::i
                // but when reevaluated is X::i
     int f() { return sizeof(c); } // OK: X::c
     char c;
     enum { i = 2 };
};


文章来源: calling functions above their declaration