2012-08-06 52 views
6
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() 
    { 
    } 
}; 

声明之上处理对函数的调用的不一致的原因是什么?我怎么能在课堂上做到这一点,但不是在命名空间或全球范围内?呼叫功能在他们的声明之上

+0

也许,编译器通过类声明中类方法实现多次,而“C”编译器只通过一次。可能是一些遗产,因为foo()本质上是C-函数 – 2012-08-06 09:55:12

+0

从静态void foo中移除静态后的结果是什么? – perilbrain 2012-08-06 09:57:09

+0

@匿名,这并没有改变任何东西 – SingerOfTheFall 2012-08-06 10:00:11

回答

3

您可以在类中定义成员函数,也可以在类声明之后或每个成员函数中定义成员函数。

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

您的代码

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() 
{  } 

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

0

嗯,也许是因为你有你的类声明在一个地方,编译器可以很容易地获得它的成员的信息。另一方面,命名空间可以让它拥有大量不同的文件,并且你不能指望编译器查看它们,因为它不知道从哪里看第一个地方。

要避免这种情况,只需使用function prototypes

0

我不确定,但我的想法是,class有点对象(严重使用),其所有内部组件一起工作(一般来说),其成员将肯定需要它的方法。

但是名称空间不同,函数不相关。这意味着函数不打算与名称空间内的其他所有函数一起使用。

因此,拆分声明和定义是您可以做的最好的事情。

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

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

  2. 函数原型在名称空间中是合法的,但不在类中。

你可以写

namespace n 
{ 
    void foo(); 

    void bar() 
    { 
     foo(); 
    } 

    void foo() 
    { 
    } 
} 

但不是

class C 
{ 
    void foo(); 

    void bar() 
    { 
     foo(); 
    } 

    void foo() 
    { 
    } 
} 

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

0

请参阅从标准

3.3.7类范围下面的引用[basic.scope.class]

1)以下规则描述在类声明的名称的范围。 1)在类中声明的名称范围不仅包含名称的声明后的 声明区域,还包含所有函数体的缺省参数 和非静态的支持或等初始化程序的 该类中的数据成员 (包括嵌套类中的这些东西)。

2)S类中使用的名称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 }; 
};