C++ 命名空间

0.来由

  • 由于最近要将代码里集成MQTT的clinet,我使用了Qt的版本—-QMQTT,这个版本使用两个重要的类Message,Frame。当我把代码添加进来进编译发现重定义的错误,引起来个错误的原因是我自己的工程里也有Message这个结构体,而且是来自于C语言的文件中,我的没有使用命名空间。

oops!!! 命名空间污染。

1、命名空间

  • 在C语言中,没有命名空间的概念,那么C语言怎么处理命名污染呢?一般来说是通过将全局的实体的名字设计得很长来避免命名空间的污染。这种方法对于程序的编写与阅读都带来了麻烦。在C++中引入了命名空间的概念。

  • 我们见得最多的是,在使用C++的标准输入输出时:

using namespace std;

cout<<"hello world";

这里就使用std这个命名空间。

1.1 命名空间的定义

//无名空间

namespace 
{
   int type;
   class book
   {

   };

   double qureyType();
} //无分号

无名空间相当于static的作用,其它作用域只在模块内。

//有名空间

namespace Library
{
   int type;
   class book
   {

   };

   double qureyType();
} //无分号

2、命名空间的使用

2.0 直接使用命名空间的限定符

当一个文件中两个命名空间同名的结构,类,函数等都要使用时,用这种方法:

Library::book b =  Library::book();
BookStore::book bb =  BookStore::book();

2.1 using 声明

当一个文件中只使用了一个命名空间的对象时,使用这种方法:

using namespace Library;
book b =  book();
  • using 的使用域是从using的声明开始,直到包含该using的声明的作用域的末尾,名字都可可见。

  • 一般放在文件头部,当然也可以在函数体内使用,当放在头文件的头部时,则源文件也是可见的,当放在函数体内部是,则是函数体内部可见。

  • 一般应避免使用这种方法,因为如次再次引入库时,很容易再次命名污染。

2.2 Qt 使用对象传信号时的定义

Q_DECLARE_METATYPE(Library::Book)

qRegisterMetaType<Library::Book>("Book");

3、 C++调用C时的命名空间定义

C语言是没有命名空间的,而我们的C++程序有很大的可能是要使用C的函数,结构等。一般我们会使用预编译的方法,如:

#ifdef __cplusplus
namespace Library {
extern "C" {
#endif

struct Message
{

};


#ifdef __cplusplus
}
}
#endif

总结

  1. 命名空间是可以是不连续的
    命名空间可以在几个部分中定义,空间由综的分离部分的总和构成,可以分散在不同的文件中。
  2. 命名空间可以使用别名
  3. 命名空间可以嵌套,(见得比较少)
<think>好的,用户想了解C++命名空间的使用方法和示例。首先,我需要整理命名空间的基本概念,然后根据引用内容来组织回答。 根据引用1,C++有两种头文件写法,老版本用#include <iostream.h>,新标准用#include <iostream>和using namespace std。命名空间的主要功能是避免命名冲突,比如不同库中的同名函数或变量。引用3提到,命名空间类似给名字加上姓氏,比如std::cout,这样可以区分不同库的同名成员。 接下来,使用方法部分,引用2提到三种方式:直接加作用域限定符、using声明整个命名空间、或只引入特定成员。比如N::a,或者using namespace N;后直接用a。引用1中的示例代码展示了如何通过作用域运算符访问成员。 需要给出示例代码,比如命名空间的创建和使用。引用3中的例子提到std::cout,可以结合这个写一个自定义命名空间的例子。比如namespace MySpace里定义变量和函数,然后在main中使用作用域限定符调用。 还要注意用户可能想知道如何简化使用,比如using namespace std;的利弊,或者用using声明部分成员,避免全局污染。引用1和3都提到了这些点,需要说明优缺点,比如全局使用可能导致冲突,推荐在局部使用或指定具体成员。 最后,相关问题需要围绕命名空间的应用场景、优化方法、与头文件的关系等展开,参考引用中的内容,比如头文件和命名空间如何配合,如何创建自己的命名空间等。 总结回答结构:引言、老版头文件对比、命名空间的功能、创建方法、三种使用方式、示例代码、结论。相关问题部分提出应用场景、优化方法、与头文件的关系等。</think>### C++命名空间的使用方法及示例 #### 1. 命名空间的功能 命名空间用于解决代码中**命名冲突**的问题。例如,不同库可能定义了同名函数或变量,通过命名空间可以区分它们,类似于“姓氏+名字”的机制[^3]。例如: - `std::cout` 表示标准库中的输出函数 - `MyLib::cout` 可能是用户自定义库中的同名函数 #### 2. 命名空间的创建 ```cpp namespace MySpace { int value = 10; void print() { std::cout << "Hello from MySpace" << std::endl; } } ``` #### 3. 命名空间的三种使用方法 1. **直接作用域限定符**(最安全) ```cpp std::cout << MySpace::value; // 明确指定命名空间[^2] ``` 2. **`using namespace` 打开整个命名空间**(可能引发冲突) ```cpp using namespace MySpace; print(); // 可直接调用,但可能与其他命名空间冲突[^1] ``` 3. **`using` 仅开放特定成员**(推荐平衡方案) ```cpp using MySpace::value; std::cout << value; // 仅开放value,降低冲突风险[^1] ``` #### 4. 完整示例代码 ```cpp #include <iostream> namespace Math { const double PI = 3.14159; double square(double x) { return x * x; } } int main() { // 方法1:直接限定 std::cout << "PI = " << Math::PI << std::endl; // 输出: 3.14159[^2] // 方法2:开放整个命名空间 using namespace Math; std::cout << "Square of 5: " << square(5) << std::endl; // 输出: 25 // 方法3:仅开放特定成员 using Math::PI; std::cout << "PI again: " << PI << std::endl; // 输出: 3.14159[^3] return 0; } ``` #### 5. 使用建议 - 在头文件中**避免使用**`using namespace`,防止污染全局命名空间 - 大型项目建议始终使用作用域限定符`::` - 短代码或局部范围可酌情使用`using`声明
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值