2013-06-25 36 views
11

当我写下面的代码就被编译并正确执行:为什么在全局范围和局部范围内使用指令的行为有所不同?

#include <iostream> 
using namespace std; 

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

namespace second 
{ 
    double x = 3.1416; 
    double y = 2.7183; 
} 

int main() { 
    using namespace first; //using derective 
    using second::y; 
    cout << x << endl; 
    cout << y << endl; 
    return 0; 
} 

但如果我写使用的主要功能之外的指令如下,

using namespace first; //using derective 
using second::y; 
int main() { 
    cout << x << endl; 
    cout << y << endl; 
    return 0; 
} 

它给出了这样的编译错误:

g++  namespace03.cpp -o namespace03 
namespace03.cpp: In function ‘int main()’: 
namespace03.cpp:20:11: error: reference to ‘y’ is ambiguous 
namespace03.cpp:13:10: error: candidates are: double second::y 
namespace03.cpp:7:7: error:     int first::y 
make: *** [namespace03] Error 1 

任何人都可以解释为什么在main和之外使用指令时,使用指令的行为会有所不同?

回答

10

使用声明就是这个声明。 main中的using second::y;类似于声明该范围内的变量y,该变量隐藏了全局名称空间范围内的任何其他y。当您在全球范围内使用using second::y;时,您并未隐藏任何名称,因为两个ys在相同的范围内。

想象一下你的第一个例子是这样(请参阅下面的评论作出解释):

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

int main() { 
    using namespace first; // This makes first::y visible hereafter 
    int y = 20; // This hides first::y (similar to using second::y) 
    cout << x << endl; 
    cout << y << endl; // Prints 20 
} 

然而,第二个例子是这样的:

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 
using namespace first; // This makes first::y visible in global scope 
int y = 20; // This is global ::y 
int main() { 
    cout << x << endl; 
    cout << y << endl; // Error! Do you mean ::y or first::y? 
} 
+0

谢谢Jesse的快速回复......请纠正我,如果我错了......但是当使用指令在主函数中仍然会有2个y的声明。如果是这样,为什么编译器只能在第二种情况下出现问题? – Amrit

+1

@ user2235938:有两个'y'的声明,但using-declaration在main内部声明'second :: y',而first :: y'在全局命名空间范围内声明。由于'second :: y'在main中被声明,它隐藏了'first :: y'。你熟悉名称隐藏吗? –

+0

对不起杰西......但我无法理解。当两个语句“首先使用命名空间; using second :: y;”在main函数内部,它应该在本地作用域中声明first :: y和second :: y,并给出编译错误。但它并没有和程序编译和运行成功。当两种语句都是主要的时候,由于含糊不清,它甚至不会被编译。请解释... – Amrit

6

有两个主要区别在使用声明和使用指令之间。

第一差异:(明显不同)。

namespace first{ 

int x=1; 
int y=2; 
} 
using first::x; //using declaration 

这将允许您使用的变量x没有命名空间名称作为一个明确的限定,并注意这不包括y

namespace first{ 
int x=1; 
int y=2; 
} 
using namespace first;// using directive 

这将允许您使用所有变量的命名空间内first命名空间名称作为一个明确的限定。


第二差:(这是你不明白)。

我会向你解释为什么当你在main函数中使用using指令和using声明时你没有错误,但是当你尝试在全局名字空间中使用它们时,你会得到一个编译时错误。

比方说,我们在全局命名空间中定义的这样的命名空间:

namespace first 
{ 
    int x = 5; 
    int y = 10; 
} 

namespace second 
{ 
    double x = 3.1416; 
    double y = 2.7183; 
} 


例1:

int main() {  
using namespace first; 
using second::y; 
    cout << x << endl; // this will output first::x; 
    cout << y << endl; // this will output second::y; 
    return 0; 
} 

的原因是使用指示符using second::y将使你的变量y看起来像是一个局部变量,范围是using-directive是你的范围sed,在这种情况下,它在主函数内部使用。而使用声明using namespace first将使得在此名称空间first内定义的变量看起来像是全局变量,并且这仅在使用using-directive的作用域内有效,在这种情况下,它位于主函数内。

所以如果你申请搞什么名堂上面说的,你就会知道,如果你做了这样的事情:

例2:

using namespace first; 
using second::y; 

int main() {  
    cout << x << endl; 
    cout << y << endl; // two definitions of y. first::y and second::y 
    return 0; 
} 

你会得到一个错误,因为这两个first::ysecond::y的行为就好像它们是在全局名称空间中定义的一样,所以您将最终打破“一个定义规则”。