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 :(得分:3)
您可以在类内部或类声明之后定义成员函数,也可以在每个函数中定义一些成员函数。
为了获得一些 here 的一致性,具有内联定义的函数的类的规则是,它仍然必须被编译,就像在类之后定义了函数一样。
您的代码
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()
{ }
现在可见性没有魔力,因为这些函数都可以看到类中声明的所有内容。
答案 1 :(得分:1)
可以重新打开命名空间,并可以在任何地方添加新内容。 无法重新打开类 - 必须放入所有内容 单个地方。
函数原型在名称空间中是合法的,但在类中不合法。
你可以写
namespace n
{
void foo();
void bar()
{
foo();
}
void foo()
{
}
}
但不是
class C
{
void foo();
void bar()
{
foo();
}
void foo()
{
}
}
因此,类需要更多这样的功能,并且为它们实现它比为命名空间更容易实现。
答案 2 :(得分:0)
也许是因为你在一个地方有你的类声明,编译器可以很容易地获得它的成员的信息。
另一方面,命名空间可以在大量不同的文件中使用它,你不能指望编译器查看它们,因为它首先不知道在哪里查看。要避免这种情况,请使用function prototypes。
答案 3 :(得分:0)
我不确定,但我的想法是class
有点像对象(使用不当),其所有内部组件一起工作(一般来说),其成员肯定会需要它的方法。
但命名空间不同,功能不相关。这意味着函数不适用于命名空间内的所有其他函数。
因此,拆分声明和定义是你能做的最好的事情。
如果foo()
需要bar()
,那么它最有可能出现在同一个声明文件中,并且会以这种方式工作
答案 4 :(得分: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 };
};