using namespace的故事

旧街凉风 提交于 2019-12-05 00:05:21

1、问题起因(使用boost.asio库时为什么如下图所示using后面不接namespace)

  

  图上的using boost::asio::ip::tcp 在using后面没有namespace,这样是正确的。那么如果加上namespace会是什么结果呢?

  

  

  加上之后如上图所示,出错。为什么?在之前我也一直不能明白原因,查了using的用法但也没有弄清楚。

  其实答案很简单:因为boost::asio::ip 是namespace,而tcp不是,他应该是一个类。

 1 namespace boost{
 2     namespace asio{
 3         namespace ip{
 4             class tcp{
 5                 ...
 6             }
 7             ...
 8         }
 9         ....
10     }
11     .....
12 }

  如上面代码所示,我们就可以写using boost::asio::ip::tcp了,这是using了一个命令空间中的tcp类的作用域。

  这个问题算是解决了。

2、问题又来了(为什么可以如下图使用)

  

   acceptor是一个(类类型)class_type,然后他又在tcp这个作用域下面,而tcp它是一个类,为什么在这个类中还有类型,其实就是boost::asio::ip::tcp::acceptor (本人的知识在这不够用了,感觉卡在这了)

  这个问题的回答是这样的,如下面代码,代码中有类A,类A中有个类型是iterator类型,这是一个typedef,因此当你使用iterator时,就需要加入A::iterator这样,上图tcp就是那个类,acceptor(应该)就是那个typedef,这样就解释清楚了。

 1 class A_iterator ;                                                                   
 2 class A {                                                                            
 3   public:                                                                            
 4     A(){std::cout << " A is start \n";}                                              
 5     ~A(){std::cout << "A is finst \n";}                                              
 6     typedef A_iterator iterator;                                                     
 7 };                                                                                   
 8 class test ;                                                                         
 9 class A_iterator {                                                                   
10   public:                                                                            
11     A_iterator(){std::cout << "A_iterator is start \n";}                             
12     ~A_iterator(){std::cout << "A_iterator is finsh \n";}                            
13     typedef test test_type ;                                                         
14 };  iterator it //错误  A::iterator it1 //正确

3、将两个问题连在一起测试

 1 #include<iostream>                                                                                                         
 2 namespace my{                                                                        
 3                                                                                      
 4   class A_iterator ;                                                                 
 5   class A {                                                                          
 6     public:                                                                          
 7       A(){std::cout << " A is start \n";}                                            
 8       ~A(){std::cout << "A is finst \n";}                                            
 9       typedef A_iterator iterator;  //我们使用iterator去定义对象,而一般不使用A_iterator 去定义对象
10   };                                                                                 
11                                                                                      
12   class test ;                                                                       
13   class A_iterator {                                                                 
14     public:                                                                          
15       A_iterator(){std::cout << "A_iterator is start \n";}                           
16       ~A_iterator(){std::cout << "A_iterator is finsh \n";}                          
17       typedef test test_type ;        //我们使用test_type去定义对象,而一般不使用test去定义对象                                               
18   };                                                                                 
19                                                                                      
20   class test {                                                                       
21     public :                                                                         
22       test(){std::cout << "test is start \n";}                                       
23       ~test(){std::cout << "test is finst \n";}                                      
24   };                                                                                 
25                                                                                      
26 }                                                                                    
27 int main()                                                                           
28 {                                                                                    
29   my::A::iterator it ; //没有问题,作用域限定全                                       
30   //my::iterator it2;  //有问题,my下面没有iterator ,应该在my::A 下面                
31   my::A::iterator::test_type t1 ; //没有问题,my命令空间中有iterator,iterator下面有test_type
32   //using namespace my //没有问题,因为my命名空间所有东西都引入进来。                
33   using my::A;         //没有问题,my是命名空间,A是类,只引入A类中的东西                                
34   //using my::A::iterator; //有问题,A是类,不是命名空间不能使用。(注意:倒数第二个作用域后面一定要是命名空间)
35   A::iterator tt2;  //没有问题                                                       
36   A::iterator::test_type tt3; //没有问题                                             
37   //iterator::test_type t2 ;                                                         
38   return 0;                                                                          
39 } 
 1 #include<iostream>                                                                                                         
 2 class B;                                                                             
 3 class A {                                                                            
 4   public:                                                                            
 5     typedef B b;                                                                     
 6 };                                                                                   
 7                                                                                      
 8 class B{                                                                             
 9   public:                                                                            
10 };                                                                                   
11                                                                                      
12 int main()                                                                           
13 {                                                                                    
14   using ::A ;                                                                        
15   A::b ins ;                                                                         
16   //b ins2 ; //有问题,需要类名限定                                                   
17   return 0;                                                                          
18 } 

4、总结:

  ①using A::B::C::D 时,D之前必须为命名空间。

    D如果是个类就可以用D::something使用,使用something必须加D::。    

  ②using namespace A::B::C::D 时,D也要为命名空间。

    D里面所有东西都引入了,可以使用命名空间,不加D::作用域

  ③在这就不难解释std::vector<int>::iterator it 

    std是命名空间,vector<>类模板,iterator是vector<>中的一个typedef

  ④类里面是一个作用域,但类不是命名空间。所以类可以被放在using最后一个命令空间的作用域下面(同时它也必须在一个命名空间下面)才能被using。

  ⑤using std::cout ; 这里应该是引入一个对象,在std命令空间里面有个cout(对象)。有点迷惑了。

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!