C++基础知识(一:命名空间的各种使用方法)

简介: C++在C的基础上引入了更多的元素,例如类,类的私密性要比C中的结构体更加优秀,引用,重载,命名空间,以及STL库,模板编程和更多的函数,在面向对象的编程上更加高效。C语言的优势则是更加底层,编译速度会更快,在编写内核时大多数都是C语言去写。在C++中,命名空间(Namespace)是一种组织代码的方式,主要用于解决全局变量、函数或类的命名冲突问题。命名空间提供了一种封装机制,允许开发者将相关的类、函数、变量等放在一个逻辑上封闭的区域中,这样相同的名字在不同的命名空间中可以共存,而不会相互干扰。


目录

一、C++和C的区别

二、命名空间

【1】接触到的第一个命名空间

【2】定义

【3】使用命名空间中的标识符

i)全局导入整体命名空间

ii)全局导入部分标识符

iii)局部导入标识符

【4】命名冲突问题*

i)两个命名空间中标识符冲突

ii)局部变量和命名空间中标识符冲突

iii)全局变量和命名空间标识符冲突

【5】匿名空间

【6】嵌套的命名空间

【7】给命名空间重命名

【8】using的另一种用法


一、C++和C的区别

面向过程语言:C       ----->重视求解过程

面向对象语言:C++   ------>重视求解的方法

C++在C的基础上引入了更多的元素,例如类,类的私密性要比C中的结构体更加优秀,引用,重载,命名空间,以及STL库,模板编程和更多的函数,在面向对象的编程上更加高效。C语言的优势则是更加底层,编译速度会更快,在编写内核时大多数都是C语言去写。

在C++中,命名空间(Namespace)是一种组织代码的方式,主要用于解决全局变量、函数或类的命名冲突问题。命名空间提供了一种封装机制,允许开发者将相关的类、函数、变量等放在一个逻辑上封闭的区域中,这样相同的名字在不同的命名空间中可以共存,而不会相互干扰。

二、命名空间

用于解决命名冲突/明明污染问题

【1】接触到的第一个命名空间

标准命名空间std:cout    endl    cin

如果代码中没有using namespace std,cout和endl会报错

image.gif 编辑

【2】定义

命名空间中可以存放,标识符:变量名、函数名、结构体名、枚举名

namespace 命名空间名

{

   定义变量;

   函数声明;

   结构体名;

   ···

};

命名空间中,只能存放函数的声明,不能放函数的定义

【3】使用命名空间中的标识符

域限定符    ::

i)全局导入整体命名空间

using namespce 命名空间名;

在该行下的所有代码,都可以使用A中的所有标识符

ii)全局导入部分标识符

using 命名空间名::标识符名;

using A::a;   ---->后面的代码都可以使用命名空间A中的标识符a

在该行下的所有代码,可以使用导入的指定的标识符

iii)局部导入标识符

在哪个位置使用,使用时直接通过域标识符来进行限定

include <iostream>
using namespace std;
namespace A
{
    int a=90;
    char c='x';
    float p=3.14;
    void fun();
};
int main()
{
    A::fun();
    cout << A::a << endl;
    return 0;
}

image.gif

include <iostream>
using namespace std;
namespace A
{
    int a=90;
    char c='x';
    float p=3.14;
    void fun();
};
//命名空间内声明fun函数,在命名空间外定义fun函数,需要给函数名加域限定符::
void A::fun()
{
    cout << "fun函数" << endl;
}
//全局导入命名空间中的所有标识符
//using namespace A;
//全局导入命名空间中的部分标识符
/*using A::fun;
using A::a;
*/
int main()
{
    A::fun();
    cout << A::a << endl;
    return 0;
}

image.gif

【4】命名冲突问题*

main.cpp:27:5: error: call to 'fun' is ambiguous

main.cpp:8:10: note: candidate function

main.cpp:12:6: note: candidate function

i)两个命名空间中标识符冲突

  1. 两个命名空间中有同名成员
  2. 同时可以访问两个命名空间中的成员

怎么解决:

  1. 命名空间名+域限定符
  2. 只导入一个命名空间,代码就只能访问导入的命名空间中的标识符

ii)局部变量和命名空间中标识符冲突

代码不会报错,但是只能默认访问局部变量

想要访问命名空间中的标识符:命名空间名+域限定符

namespace A
{
    int a=90;
    char c='x';
    float p=3.14;
    void fun();
};
int main()
{
    //在使用的位置使用域限定符
    A::fun();
    int a=100;
    cout << A::a << endl;
    cout << "B中的a=" << B::a << endl;
    return 0;
}

image.gif

iii)全局变量和命名空间标识符冲突

访问全局变量:只在标识符前加域限定符      ::a ----->访问全局变量a

访问命名空间中标识符:命名空间名+域限定符

include <iostream>
using namespace std;
int a=1000;   //定义了一个全局变量a
namespace A
{
    int a=90;
    char c='x';
    float p=3.14;
    void fun();
};
int main()
{
    //在使用的位置使用域限定符
    A::fun();
    cout << ::a << endl;    //加上域限定符访问全局变量的a,
    //因为全局变量,默认在匿名空间中
    cout << "B中的a=" << B::a << endl;
    return 0;
}

image.gif

【5】匿名空间

没有名字的命名空间,就是匿名空间

匿名空间中的标识符的访问方式:

::标识符名

注意:匿名空间中的标识符尽量不要和全局变量冲突

include <iostream>
using namespace std;
int a=1000;   //定义了一个全局变量a
namespace B
{
     int a=130;
}
//命名空间内声明fun函数,在命名空间外定义fun函数,需要给函数名加域限定符::
void A::fun()
{
    cout << "fun函数" << endl;
}
//全局导入命名空间中的所有标识符
using namespace A;
//using namespace B;
//匿名空间,尽量不要使用匿名空间
namespace  {
     int a = 2000;
     char c;
}
int main()
{
    //在使用的位置使用域限定符
    A::fun();
    cout << ::a << endl;    //加上域限定符访问全局变量的a,
    //因为全局变量,默认在匿名空间中
    cout << "B中的a=" << B::a << endl;
    return 0;
}

image.gif

【6】嵌套的命名空间

一个命名空间定义在另一个命名空间内

访问时需要逐层查找

include <iostream>
using namespace std;
namespace A1 {
     int num1 = 10;
     int num2 = 30;
     namespace A2
     {
         int num1=1;
         int num2=90;
         int x = 7;
     }
}
using namespace A1;
using namespace A1::A2;
int main()
{
    //想要访问A2中的num1
    //由于A2是包含在A1内的,想要访问到A2需要一层一层访问
    cout << A1::A2::num1 << endl;
    //cout << num2 << endl;   一定构成命名冲突问题
    cout << A1::num2 << endl;
    return 0;
}

image.gif

【7】给命名空间重命名

namespace  新的名字 = 旧的名字;

include <iostream>
using namespace std;
namespace A1 {
     int num1 = 10;
     int num2 = 30;
     namespace A2
     {
         int num1=1;
         int num2=90;
         int x = 7;
     }
}
using namespace A1;
using namespace A1::A2;
int main()
{
    //想要访问A2中的num1
    //由于A2是包含在A1内的,想要访问到A2需要一层一层访问
    cout << A1::A2::num1 << endl;
    //cout << num2 << endl;   一定构成命名冲突问题
    cout << A1::num2 << endl;
    return 0;
}

image.gif

【8】using的另一种用法

using还可以用于类型重定义

C++ 11标准才能使用using实现重定义

typedef int arr[5];<===>arr相当于int [5]

typedef int p;   <===>p后面就相当于int

include <iostream>
using namespace std;
namespace p = A1;    //把命名空间A1重命名为p,后面既可以使用A1访问也可以使用p访问
using namespace A1;
using namespace A1::A2;
int main()
{
    //使用suing把int,重命名为INT,后面使用哪一个都可以定义整形变量
    using INT = int;
    INT a = 90;
    cout << a << endl;
    cout << sizeof(a) << endl;
    return 0;
}

image.gif

相关文章
|
1月前
|
编译器 C++
C++进阶之路:何为命名空间、缺省参数与函数重载
C++进阶之路:何为命名空间、缺省参数与函数重载
22 3
|
18天前
|
C++
C++命名空间(namespace)的使用
C++命名空间(namespace)的使用
|
21天前
|
人工智能 安全 编译器
【C++入门】—— C++入门 (上)_命名空间
【C++入门】—— C++入门 (上)_命名空间
17 2
|
2天前
|
C++
C++基础知识(二:引用和new delete)
引用是C++中的一种复合类型,它是某个已存在变量的别名,也就是说引用不是独立的实体,它只是为已存在的变量取了一个新名字。一旦引用被初始化为某个变量,就不能改变引用到另一个变量。引用的主要用途包括函数参数传递、操作符重载等,它可以避免复制大对象的开销,并且使得代码更加直观易读。
|
2天前
|
算法 编译器 C++
C++基础知识(三:哑元和内联函数和函数重载)
在C++编程中,"哑元"这个术语虽然不常用,但可以理解为在函数定义或调用中使用的没有实际功能、仅作为占位符的参数。这种做法多见于模板编程或者为了匹配函数签名等场景。例如,在实现某些通用算法时,可能需要一个特定数量的参数来满足编译器要求,即使在特定情况下某些参数并不参与计算,这些参数就可以被视为哑元。
|
2天前
|
C++
C++基础知识(四:类的学习)
类指的就是对同一类对象,把所有的属性都封装起来,你也可以把类看成一个高级版的结构体。
|
2天前
|
自然语言处理 程序员 C++
C++基础知识(五:运算符重载)
运算符重载是C++中的一项强大特性,它允许程序员为自定义类型(如类或结构体)重新定义标准运算符的行为,使得这些运算符能够适用于自定义类型的操作。这样做可以增强代码的可读性和表达力,使得代码更接近自然语言,同时保持了面向对象编程的封装性。
|
2天前
|
存储 编译器 C++
C++基础知识(六:继承)
多态是面向对象编程的四大基本原则之一,它让程序能够以统一的接口处理不同的对象类型,从而实现了接口与实现分离,提高了代码的灵活性和复用性。多态主要体现在两个层面:静态多态(编译时多态,如函数重载)和动态多态(运行时多态,主要通过虚函数实现)。
|
2天前
|
存储 编译器 C++
C++基础知识(七:多态)
多态是面向对象编程的四大基本原则之一,它让程序能够以统一的接口处理不同的对象类型,从而实现了接口与实现分离,提高了代码的灵活性和复用性。多态主要体现在两个层面:静态多态(编译时多态,如函数重载)和动态多态(运行时多态,主要通过虚函数实现)。
|
2天前
|
存储 算法 程序员
C++基础知识(八:STL标准库(Vectors和list))
C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), lists(链表), 和 stacks(栈)等. STL容器的提供是为了让开发者可以更高效率的去开发,同时我们应该也需要知道他们的底层实现,这样在出现错误的时候我们才知道一些原因,才可以更好的去解决问题。

热门文章

最新文章

相关实验场景

更多