C++项目中自定义命名空间MyNamespace的头文件与源文件使用方式
自定义命名空间MyNamespace在头文件与CPP文件中的正确用法
刚好最近经常跟命名空间打交道,我来给你捋清楚自定义命名空间MyNamespace在头文件和CPP文件里的正确使用姿势~
头文件中的写法
在头文件里我们主要做类和函数的声明,这里有两种完全合法的写法,你可以根据习惯和场景选择:
写法一:显式带上命名空间前缀
即使已经处于MyNamespace的作用域内,也可以给内部成员显式加上MyNamespace::前缀,这种写法在存在同名类型/函数时,能有效避免歧义:
// MyNamespace.h #pragma once namespace MyNamespace{ class MyOtherClass; // 前置声明 class MyClass{ // 显式指定参数类型属于MyNamespace MyClass(MyNamespace::MyClass&) {} MyClass(MyNamespace::MyOtherClass&) {} MyNamespace::MyClass& operator=(const MyNamespace::MyClass&) {return *this;} }; inline void someFunc(MyNamespace::MyClass& obj){}; }
写法二:省略命名空间前缀
因为我们已经在MyNamespace的作用域内部,编译器会自动识别当前作用域内的类型和函数,所以可以直接省略前缀,写法更简洁:
// MyNamespace.h #pragma once namespace MyNamespace{ class MyOtherClass; // 前置声明 class MyClass{ MyClass(MyClass&) {} MyClass(MyOtherClass&) {} MyClass& operator=(const MyClass&) {return *this;} }; inline void someFunc(MyClass& obj){}; }
这两种写法没有绝对优劣,完全取决于你的代码风格和是否存在歧义风险。
CPP文件中的写法
CPP文件主要用来实现头文件中声明的成员函数,同样有两种常用写法:
写法一:打开命名空间实现
直接在CPP文件中打开MyNamespace,内部的成员函数只需用类名加作用域解析符即可,写法清爽简洁:
// MyNamespace.cpp #include "MyNamespace.h" namespace MyNamespace { // 实现MyClass的拷贝构造 MyClass::MyClass(MyClass&) { // 这里编写构造逻辑 } // 实现赋值运算符重载 MyClass& MyClass::operator=(const MyClass& other) { if (this != &other) { // 编写赋值逻辑 } return *this; } // 实现someFunc函数 void someFunc(MyClass& obj) { // 编写函数逻辑 } }
写法二:全程显式指定命名空间
如果不想打开命名空间,或者担心嵌套命名空间导致混淆,也可以全程用MyNamespace::指定作用域,虽然代码稍长,但可读性更强:
// MyNamespace.cpp #include "MyNamespace.h" MyNamespace::MyClass::MyClass(MyNamespace::MyClass&) { // 编写构造逻辑 } MyNamespace::MyClass& MyNamespace::MyClass::operator=(const MyNamespace::MyClass& other) { if (this != &other) { // 编写赋值逻辑 } return *this; } void MyNamespace::someFunc(MyNamespace::MyClass& obj) { // 编写函数逻辑 }
最后提醒一句:头文件一定要加重复包含保护,比如上面用的#pragma once,或者传统的#ifndef+#define+#endif结构,防止头文件被多次包含导致编译错误。
内容的提问来源于stack exchange,提问作者AdyAdy
相关产品推荐
相关产品推荐

