[英]calling functions above their declaration
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()
{
}
};
处理对声明之外的函数调用的这种不一致背后的理由是什么? 为什么我可以在一个类中完成它,但不能在命名空间内或全局范围内?
您可以在类内部或类声明之后定义成员函数,也可以在每个函数中定义一些成员函数。
为了在这里获得一些一致性,具有内联定义的函数的类的规则是它仍然必须被编译,就像在类之后定义函数一样。
你的代码
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()
{ }
现在可见性没有魔力,因为函数都可以看到类中声明的所有内容。
可以重新打开命名空间,并可以在任何地方添加新内容。 类不能重新打开 - 所有内容必须放在一个地方。
函数原型在命名空间中是合法的,但在类中则不合法。
你可以写
namespace n
{
void foo();
void bar()
{
foo();
}
void foo()
{
}
}
但不是
class C
{
void foo();
void bar()
{
foo();
}
void foo()
{
}
}
所以类需要更多这样的功能,并且为它们实现它比为命名空间更容易。
也许是因为你在一个地方有你的类声明,编译器可以很容易地获得它的成员的信息。
另一方面,命名空间可以在大量不同的文件中使用它,并且您不能指望编译器查看它们,因为它不知道首先要查看的位置。
为避免这种情况,只需使用函数原型 。
我不确定,但我的想法是,一个class
在某种程度上是一个对象 (使用不当),其所有内部组件一起工作(一般来说),其成员肯定需要它的方法。
但命名空间不同,功能不相关。 这意味着函数不适用于命名空间内的所有其他函数。
因此,拆分声明和定义是您可以做的最好的事情。
如果foo()
需要bar()
它很可能会在同一个声明文件中,并且会以这种方式工作
请参阅标准中的以下引用
3.3.7类范围[basic.scope.class]
1)以下规则描述了在类中声明的名称范围。 1)在类中声明的名称的潜在范围不仅包括名称声明点后面的声明性区域,还包括所有函数体,默认参数和非静态数据成员的括号或均衡初始化。 class(包括嵌套类中的这类东西)。
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 };
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.