zoukankan      html  css  js  c++  java
  • c++,命名空间(namespace)

    1.什么是命名空间:

      命名空间实际上就是一个由程序设计者命名的内存区域,程序设计者可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。

    2.命名空间的作用:

      命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。

      在 C语言中定义了3个层次的作用域,即文件(编译单元)、函数和复合语句。C++又引入了类作用域,类是出现在文件内的。在不同的作用域中可以定义相同名字的变量,互不于扰,系统能够区别它们。

    3.命名空间的定义和基本使用方法:

    #include <iostream>
    using namespace std;
    // 在声明一个命名空间时,花括号内不仅可以包括变量,而且还可以包括以下类型:
    //     ·变量(可以带有初始化);
    //     ·常量;
    //     ·数(可以是定义或声明);
    //     ·结构体;
    //     ·类;
    //     ·模板;
    //     ·命名空间(在一个命名空间中又定义一个命名空间,即嵌套的命名空间)。
    //     例如
    namespace NS
    { 
        const double RATE=0.08; //常量
        double pay = 200;       //变量
        double tax()            //函数
        {
            return pay * RATE;
        }
        namespace InterNS       //嵌套的命名空间
        {
            int age = 29;
        }
    }
    
    //如果想输出命名空间NS中成员的数据,可以采用下面的方法:
    void func()
    {
        cout<<NS::RATE<<endl;
        cout<<NS::pay<<endl;
        cout<<NS::tax()<<endl;
        cout<<NS::InterNS::age<<endl; //需要指定外层的和内层的命名中间名
    
    }
    
    int main()
    {
        func();
        //pay = 1000; //error C2065: “pay”: 未声明的标识符 
        while(1);
        return 0;
    }
    // 
    // 0.08
    // 200
    // 16
    // 29

    4.利用命名空间来解决程序名字冲突问题实例:

    #include <iostream>
    using namespace std;
    //-------------------------------------------------------------
    //header1.h
    #ifndef HEADER1_H_
    #define HEADER1_H_
    using namespace std;
    #include <string>
    #include <cmath>
    namespace ns1
    {
        class Student//命名空间中的类
        {
        public:
            Student(int n,string nam,int a)
                :num(n),
                name(nam),
                age(a)
            {
            }
            void get_data();
        private:
            int num;
            string name;
            int age;
        };
        void Student::get_data()
        {
            cout << "num: " <<num << " name: "<< name<<" age: "<<age<< endl;
        }
    
    
        double fun(double a,double b)//命名空间中的方法
        {
            return sqrt(a + b);
        }
    }
    
    #endif /* HEADER1_H_ */
    //-------------------------------------------------------------
    
    //header2.h
    #ifndef HEADER2_H_
    #define HEADER2_H_
    
    #include <cmath>
    namespace ns2
    {
        class Student//同名的类
        {
        public :
    
            Student(int n,string nam, char s)
            : num(n),
              name(nam),
              sex(s) 
            {
            };
            void get_data();
        private:
            int num;
            string name;
            char sex;
        };
    
        void Student::get_data()
        {
            cout << "num: " << num << " name: " <<name<< " sex: "<<sex << endl;
        }
    
    
        double fun(double a,double b) //同名的方法
        {
            return sqrt(a - b);
        }
    }
    
    #endif /* HEADER2_H_ */
    //-------------------------------------------------------------
    # include <iostream>
    # include "header1.h"
    # include "header2.h"
    int main()
    {
        ns1 :: Student stud1(10086,"xiaobao",18); //
        stud1.get_data();
        cout <<"n1::fun(a8,4) = "<< ns1 :: fun(8,4) << endl;
    
    
        ns2 :: Student stud2(10087,"xiaobei",'m');
        stud2.get_data();
        cout <<"n2::fun(a8,4) = "<< ns2:: fun(8,4) << endl;
    
    
        while(1);
        return 0;
    }
    
    // num: 10086 name: xiaobao age: 18
    // n1::fun(a8,4) = 3.4641
    
    // num: 10087 name: xiaobei sex: m
    // n2::fun(a8,4) = 2

    5.使用命名空间的方法:

      // 1、使用命名空间名::命名空间成员名[上面已讲]

    #include <iostream>
    using namespace std;
    namespace Television //声明命名空间,名为Television
    {
        void show()
        {
            cout<<"showing..."<<endl;
        }
    }
    namespace TV=Television;//别名,等同于本名
        
    int main()
    {    
            Television::show();//使用命名空间名::命名空间成员名
            //TV::show();//同上
    
            while(1);
            return 0 ;
    }
    //showing...

      // 2、使用命名空间别名

    namespace Television //声明命名空间,名为Television
    {
        void show()
        {
            cout<<"showing..."<<endl;
        }
    }
    namespace TV=Television;
        
    int main()
    {
            TV::show();
            while(1);
            return 0 ;
    }
    //showing...

      // 3、使用using 命名空间::成员

    #include <iostream>
    using namespace std;
    namespace Television //声明命名空间,名为Television
    {
        void show()
        {
            cout<<"showing..."<<endl;
        }
    }
    namespace TV=Television;
        
    
    using  TV::show; //使用using 命名空间成员名
    int main()
    {    
            show();//这里就可以不在加上命名空间作用域了
    
            while(1);
            return 0 ;
    }
    //showing...

      // 4、使用using namespace 命名空间名

    #include <iostream>
    using namespace std;
    namespace Television //声明命名空间,名为Television
    {
        void show()
        {
            cout<<"showing..."<<endl;
        }
    }
    namespace TV=Television;
        
    
    using namespace TV;
    int main()
    {    
            show();
    
            while(1);
            return 0 ;
    }
    //showing...

    在使用using namespace命名空间名的情况下,如果在同一作用域中同时引入了两个命名空间nsl和ns2,其中有同名的类和函数。在出现Student时,无法判定是哪个命名空间中的 Student,出现二义性,编译出错。因此只有在使用命名空间数量很少,以及确保这些命名空间中没有同名成员时才用using namespace语句。[错误范例,代码如下:]

    //-------------------------------------------------------------
    //header1.h
    #ifndef HEADER1_H_
    #define HEADER1_H_
    using namespace std;
    #include <string>
    #include <cmath>
    namespace ns1
    {
        class Student//命名空间中的类
        {
        public:
            Student(int n,string nam,int a)
                :num(n),
                name(nam),
                age(a)
            {
            }
            void get_data();
        private:
            int num;
            string name;
            int age;
        };
        void Student::get_data()
        {
            cout << "num: " <<num << " name: "<< name<<" age: "<<age<< endl;
        }
    
    
        double fun(double a,double b)//命名空间中的方法
        {
            return sqrt(a + b);
        }
    }
    
    #endif /* HEADER1_H_ */
    //-------------------------------------------------------------
    
    //header2.h
    #ifndef HEADER2_H_
    #define HEADER2_H_
    
    #include <cmath>
    namespace ns2
    {
        class Student//同名的类
        {
        public :
    
            Student(int n,string nam, char s)
            : num(n),
              name(nam),
              sex(s) 
            {
            };
            void get_data();
        private:
            int num;
            string name;
            char sex;
        };
    
        void Student::get_data()
        {
            cout << "num: " << num << " name: " <<name<< " sex: "<<sex << endl;
        }
    
        double fun(double a,double b) //同名的方法
        {
            return sqrt(a - b);
        }
    }
    
    #endif /* HEADER2_H_ */
    //-------------------------------------------------------------
    # include <iostream>
    # include "header1.h"
    # include "header2.h"
    int main()
    {
        using namespace ns1;
        using namespace ns2;//冲突
    
        
        Student stud1(10086,"xiaobao",18); // error C2872: “Student”: 不明确的符号
        stud1.get_data();
        cout <<"n1::fun(a8,4) = "<< ns1 :: fun(8,4) << endl;
    
    
        Student stud2(10087,"xiaobei",'m');// error C2872: “Student”: 不明确的符号
        stud2.get_data();
        cout <<"n2::fun(a8,4) = "<< ns2:: fun(8,4) << endl;
    
    
        while(1);
        return 0;
    }

    6、无名的命名空间

      无名命名空间作用域 : 确切地说,是从声明无名命名空间的位置开始到本文件结束。

      在文件中使用无名命名空间的成员,不必(也无法)用命名空间名限定。

    //有名的命名空间
    namespace EX_NS
    {
        void show()
        {
            cout<<"ex showing..."<<endl;
        }
    }
    
    // 命名空间没有名字,在其他文件中显然无法引用,它只在本文件的作用域内有效。
    // 无名命名空间的成员作用域:确切地说,是从声明无名命名空间的位置开始到文件结束。
    // 在文件A中使用无名命名空间的成员,不必(也无法)用命名空间名限定。
    
    //无名命名空间
    namespace 
    {
        void show()
        {
            cout<<"showing..."<<endl;
        }
    }
    void func(void)
    {
        EX_NS::show();
        show();//要使用无名命名空间,func不能再它之前定义。
    }
    
    int main()
    {
        func();
        while(1);
        return 0;
    }

      下面这样是错误的:

    using namespace EX_NS ;
    void func(void)
    {
        EX_NS::show();
        show(); //error C2668: “EX_NS::show”: 对重载函数的调用不明确
    }

    7、因为多个命名空间可能有相同成员,除了std之外,在使用命名空间较多的情况下,一般不直接using namespace 命名空间。也一般不直接使用无名的命名空间。[个人习惯]

    为减少出错机会,可用若干个"using 命名空间::成员”声明来代替“using namespace 命名空间”声明,如果较多使用,可以在同文件中专门书写。

      

    参考:

    1. c++命名空间
      http://blog.csdn.net/randyjiawenjie/article/details/6637043

  • 相关阅读:
    第05组 Beta版本演示
    第05组 Beta冲刺(4/4)
    第05组 Beta冲刺(3/4)
    第05组 Beta冲刺(2/4)
    第05组 Beta冲刺(1/4)
    第05组 Alpha事后诸葛亮
    第05组 Alpha冲刺(4/4)
    第05组 Alpha冲刺(3/4)
    第05组 Alpha冲刺(2/4)
    300iq Contest 3 C. Cells Blocking
  • 原文地址:https://www.cnblogs.com/mylinux/p/4096783.html
Copyright © 2011-2022 走看看