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++】如何巧妙运用C++命名空间:初学者必备指南
|
3月前
|
程序员 C++ 开发者
C++命名空间揭秘:一招解决全局冲突,让你的代码模块化战斗值飙升!
【8月更文挑战第22天】在C++中,命名空间是解决命名冲突的关键机制,它帮助开发者组织代码并提升可维护性。本文通过一个图形库开发案例,展示了如何利用命名空间避免圆形和矩形类间的命名冲突。通过定义和实现这些类,并在主函数中使用命名空间创建对象及调用方法,我们不仅解决了冲突问题,还提高了代码的模块化程度和组织结构。这为实际项目开发提供了宝贵的参考经验。
61 2
|
2月前
|
程序员 C++ 容器
C++编程基础:命名空间、输入输出与默认参数
命名空间、输入输出和函数默认参数是C++编程中的基础概念。合理地使用这些特性能够使代码更加清晰、模块化和易于管理。理解并掌握这些基础知识,对于每一个C++程序员来说都是非常重要的。通过上述介绍和示例,希望能够帮助你更好地理解和运用这些C++的基础特性。
40 0
|
3月前
|
编译器 C语言 C++
C++入门 | 命名空间、输入输出、缺省参数
C++入门 | 命名空间、输入输出、缺省参数
44 4
|
2月前
|
C语言 C++
C++(六)Namespace 命名空间
命名空间(Namespace)是为了解决大型项目中命名冲突而引入的机制。在多库集成时,不同类库可能包含同名函数或变量,导致冲突。C++通过语法形式定义了全局无名命名空间,并允许对全局函数和变量进行作用域划分。命名空间支持嵌套与合并,便于协同开发。其使用需谨慎处理同名冲突。
|
4月前
|
安全 编译器 C++
C++一分钟之-C++中的属性命名空间
【7月更文挑战第22天】C++11引入属性作为元数据,虽无内置属性命名空间,但可通过自定义属性与命名空间组合实现类似效果。例如,创建`perf`命名空间存放`slow`和`fast`属性来标记函数性能。正确使用属性需注意位置、避免重复和确保与实现一致,以提升代码可读性和编译器理解。通过模拟属性命名空间,可以更有效地管理和使用属性。
43 1
|
3月前
|
安全 C++ Windows
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
|
4月前
|
小程序 C++
【C++入门 二 】学习使用C++命名空间及其展开
【C++入门 二 】学习使用C++命名空间及其展开
|
4月前
|
C++
C++基础知识(二:引用和new delete)
引用是C++中的一种复合类型,它是某个已存在变量的别名,也就是说引用不是独立的实体,它只是为已存在的变量取了一个新名字。一旦引用被初始化为某个变量,就不能改变引用到另一个变量。引用的主要用途包括函数参数传递、操作符重载等,它可以避免复制大对象的开销,并且使得代码更加直观易读。
|
4月前
|
算法 编译器 C++
C++基础知识(三:哑元和内联函数和函数重载)
在C++编程中,"哑元"这个术语虽然不常用,但可以理解为在函数定义或调用中使用的没有实际功能、仅作为占位符的参数。这种做法多见于模板编程或者为了匹配函数签名等场景。例如,在实现某些通用算法时,可能需要一个特定数量的参数来满足编译器要求,即使在特定情况下某些参数并不参与计算,这些参数就可以被视为哑元。