用using指示符声明namespace的一点体会

以前用C#.NET的时候,没有深究过namespace的用法,最近看C++ Primer中关于namespace的讲解有自己的一点体会:
首先,来看我写的一小段代码:
#include <iostream>

using namespace std;

void doSomething()
{
 cout << "doSomething() called" << endl;
}

namespace first
{
 void doSomething()
 {
  cout << "first::second::third::doSomething() called" << endl;
 }

 namespace second
 {
  void doSomething()
  {
   cout << "first::second::doSomething() called" << endl;
  }

  namespace third
  {
   void doSomething()
   {
    cout << "first::second::third::doSomething() called" << endl;
   }
  }
 }

 namespace test
 {
  namespace testInner
  {
   void func()
   {
    using namespace first::second::third;

    doSomething();
   }
  } 
 }
}

int main()
{
 test::testInner::func();

 return 0;
}

    粗看起来,似乎没什么错误,可是编译未能通过,报错:error C2668: 'doSomething' : ambiguous call to overloaded function Error executing cl.exe.
究其原因是因为在函数func()中,语句using namespace first::second::third将命名空间first::second::third下的所有成员定义为first下的的成员,而first::second::third::doSomething()与first::doSomething()重复定义(函数签名相同,未能构成重载)。
    为了使程序能编译通过,解决方法之一就是将first::doSomething()删除,比如:

//...原程序不变

namespace first
{
// void doSomething() // 删除此函数
// {
//  cout << "first::second::third::doSomething() called" << endl;
// }

 namespace second
 {

//...main()函数不变

    此时再次编译即可通过。那么现在运行结果是什么呢?前面说到,语句using namespace first::second::third将命名空间first::second::third下的所有成员声明为first下的的成员,因而此时first::second::third::doSomething()应覆盖::doSomething(),故结果输出:


first::second::third::doSomething() called

小结:
    在如下代码中,using指示符将命名空间namespaceHome::namespace1::...::namespaceN下的成员声明为namespaceHome下的成员,即using指示符所在的命名空间(namespaceHome::namespaceU1::..namespaceUM)与using指示符所声明的命名空间(namespaceHome::namespace1::...::namespaceN)所在的第一个母命名空间下的成员。
namespaceHome
{
 namespace1
 {
  ... // N层命名空间
  {
   namespaceN
   {
    ... // 各成员
   }
  }
 }

 namespaceU1
 {
  ... // M层命名空间
  {
   namespaceUM
   {
    using namespace1::...::namespaceN; 
   }
  }
 }
}


关于using声明using指示符的区别

10-26

using声明能使名字空间中的一个变量或函数在名字空间外可见,而using指示符则使整个名字空间中的成员在名字空间外都可见,就像去掉名字空间一样.rn 在重载函数解析的第一步,确定候选函数集时,嵌套域中的using声明将隐藏而不是重载外围域中的同名函数,而不论将using指示符放在全局域中还是局部域中,都不会隐藏外围域中的同名函数,而是重载它们.(见c++ primer 394--397)rn示例:rnnamespace lib_r_usrn int max(int,int);rn double max(double,double);rn rnchar max(char,char);rn using libs_r_us::max;rn max(87,65);rn max(35.3,76.6);rn max('j','l'); rnrn三个函数分别调用max(int,int); max(double,double); max(int,int);rn---------------------------rnrnnamespace lib_r_usrn int max(int,int);rn double max(double,double);rn rnchar max(char,char);rnusing libs_r_us::max;rn max(87,65);rn max(35.3,76.6);rn max('j','l'); rnrn三个函数分别调用max(int,int); max(double,double); max(char,char);rn----------------------------------------rnnamespace lib_r_usrn int max(int,int);rn double max(double,double);rn rnchar max(char,char);rnusing namespace libs_r_us;rn max(87,65);rn max(35.3,76.6);rn max('j','l'); rnrn三个函数分别调用max(int,int); max(double,double); max(char,char);rn__________________________________rnnamespace lib_r_usrn int max(int,int);rn double max(double,double);rn rnchar max(char,char);rnrn using namespace libs_r_us;rn max(87,65);rn max(35.3,76.6);rn max('j','l'); rnrn三个函数分别调用max(int,int); max(double,double); max(char,char);rn_____________________________________rn请解释一下原因.rnrn

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试

关闭