前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C++ 语言】命名空间 ( namespace | 命名空间定义 | 命名空间嵌套 | 域作用符 | 与 include 对比 )

【C++ 语言】命名空间 ( namespace | 命名空间定义 | 命名空间嵌套 | 域作用符 | 与 include 对比 )

作者头像
韩曙亮
发布于 2023-03-27 08:50:04
发布于 2023-03-27 08:50:04
2.7K00
代码可运行
举报
运行总次数:0
代码可运行

文章目录

命名空间简介

命名空间 ( namespace ) :

  • 1.命名空间简介 : C++ 中的命名空间相当于 Java 中的 Package 包 , 最常用的命名空间是 std , 基本每个项目都要使用 , 代码如下 :
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using namespace std;
  • 2.命名空间作用 : 平时使用的 cout , endl 等都是在 std 命名空间 中定义的 , 如果不声明 std 命名空间 , 那么命令行输出使用的 cout 和 endl 必须使用 域作用符 "::" 进行访问 ;
    • ① 域作用符访问方法 : 命名空间 :: 变量名
    • ② 不声明 std 命名空间使用 cout 方法 : std::cout
    • ③ 不声明 std 命名空间使用 endl方法 : std::endl
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	// 命名空间 相当于 Java 中的 Package 包 , 
	//	上面的 cout endl string 等都定义在 std 命名空间中
	// 如果没有 using namespace std; 声明命名空间 , 
	//	那么必须使用域作用符 "::" ( 两个冒号 ) , 否则全都会报错
	std::cout << 
		"没有使用命名空间 需要使用 std::cout << ... << std::endl 打印" 
		<< std::endl;
  • 3.执行结果 :
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
没有使用命名空间 需要使用 std::cout << ... << std::endl 打印

自定义命名空间

自定义命名空间 ( namespace ) :

  • 1.定义方式 : 使用 “namespace 命名空间名称 {}” 格式 , 定义命名空间 , 可以将变量和方法定义在命名空间中 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//自定义命名空间
namespace mynamespace {

	//调用时 需要调用 mynamespace::say_hi() 方法进行调用
	void say_hi() {
		//注意 : 下面的 cout 和 endl 定义在 std 命名空间中
		//如果没有声明 using namespace std; , 就必须使用域作用符号 "::" 才能访问
		//域作用符格式 : 命名空间::调用内容
		std::cout << "自定义命名空间 mynamespace say_hi() 方法 : Hi!" << std::endl;
	}
}
  • 2.声明自定义的命名空间 : 使用 “using namespace 命名空间名称;” 声明命名空间 ; 下面是声明命名空间 与 不声明 的区别 :
    • ① 声明命名空间 : 可以直接调用命名空间中的方法 ;
    • ② 没有声明该命名空间 : 就必须使用 “命名空间名称::方法名()” 域作用符调用命名空间定义的方法 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//声明自定义的命名空间 , 声明 外层命名空间 , 
//可以直接调用 say_hi() 方法 ; 
//调用内层的 say_hi_inner() 方法需要使用 myinnernamespace::say_hi_inner() 进行调用
using namespace mynamespace;
  • 3.访问命名空间中的方法 ( 没有声明的情况下 ) : 如果没有声明命名空间 , 需要调用 “命名空间名称::方法名()” 的方式调用命名空间中的方法 , 这里想要调用 mynamespace 命名空间的 say_hi() 方法 , 就需要按照下述代码进行操作 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//没有声明命名空间 : 调用自定义的 mynamespace 命名空间中的 say_hi 方法 , 必须使用域作用符
	mynamespace::say_hi();
  • 4.访问命名空间中的方法 ( 已经声明的情况下 ) : 如果已经声明了命名空间 , 就可以直接调用命名空间中的方法 , 不需要使用 域作用符 访问命名空间中的方法 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//声明命名空间 : 如果声明了 外层的命名空间 , 可以调用外层命名空间中定义的 say_hi() 方法
	say_hi();
  • 5.命名空间相关的代码 : 包括 ① 命名空间定义 , ② 声明 , ③ 使用 ( a. 声明命名空间 / b. 未声明命名空间 ) 的代码 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//1.命名空间定义 : 自定义命名空间
namespace mynamespace {

	//调用时 需要调用 mynamespace::say_hi() 方法进行调用
	void say_hi() {
		//注意 : 下面的 cout 和 endl 定义在 std 命名空间中
		//如果没有声明 using namespace std; , 就必须使用域作用符号 "::" 才能访问
		//域作用符格式 : 命名空间::调用内容
		std::cout << "自定义命名空间 mynamespace say_hi() 方法 : Hi!" << std::endl;
	}
}

//2. 命名空间声明
//声明自定义的命名空间 , 声明 外层命名空间 , 
//可以直接调用 say_hi() 方法 ; 
//调用内层的 say_hi_inner() 方法需要使用 myinnernamespace::say_hi_inner() 进行调用
using namespace mynamespace;

//下面是方法中的代码

	//3. 没有声明命名空间的情况下调用命名空间中的方法
	//没有声明命名空间 : 调用自定义的 mynamespace 命名空间中的 say_hi 方法 , 必须使用域作用符
	mynamespace::say_hi();

	//4. 已经声明命名空间的情况下调用命名空间中的方法
	//声明命名空间 : 如果声明了 外层的命名空间 , 可以调用外层命名空间中定义的 say_hi() 方法
	say_hi();
  • 6.代码执行结果 :
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
自定义命名空间 mynamespace say_hi() 方法 : Hi!
自定义命名空间 mynamespace say_hi() 方法 : Hi!

自定义嵌套命名空间

自定义嵌套命名空间 :

  • 1.嵌套命名空间简介 : 命名空间内部再定义一个命名空间 , 这种情况就是嵌套的命名空间 ; 如下代码 , myinnernamespace 就是定义的内层的命名空间 , 如果要访问内层命名空间的方法 , 需要两个域作用符才能访问 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//命名空间定义 : 自定义命名空间
namespace mynamespace {

	//调用时 需要调用 mynamespace::say_hi() 方法进行调用
	void say_hi() {
		//注意 : 下面的 cout 和 endl 定义在 std 命名空间中
		//如果没有声明 using namespace std; , 就必须使用域作用符号 "::" 才能访问
		//域作用符格式 : 命名空间::调用内容
		std::cout << "自定义命名空间 mynamespace say_hi() 方法 : Hi!" << std::endl;
	}

	//嵌套的命名空间需要调用 mynamespace::myinnernamespace::say_hi() 才能调用该方法
	namespace myinnernamespace {
		void say_hi_inner() {
			//注意 : 下面的 cout 和 endl 定义在 std 命名空间中
			//如果没有声明 using namespace std; , 就必须使用域作用符号 "::" 才能访问
			//域作用符格式 : 命名空间::调用内容
			std::cout << "自定义嵌套的命名空间 myinnernamespace say_hi_inner() 方法 : Hi Inner!" << std::endl;
		}
	}
}
  • 2.声明外层命名空间 : 需要使用 “using 外层命名空间名称;” 方式进行声明 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//声明自定义的命名空间 , 声明 外层命名空间 , 
//可以直接调用 say_hi() 方法 ; 
//调用内层的 say_hi_inner() 方法需要使用 myinnernamespace::say_hi_inner() 进行调用
using namespace mynamespace;
  • 3.声明内层命名空间 : 需要使用 “using 外层命名空间名称::内层命名空间名称;” 方式进行声明 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//声明内层的命名空间 , 需要使用 外层命名空间::内层命名空间 进行声明
//这样就可以直接调用内层命名空间的 say_hi_inner() 方法了
using namespace mynamespace::myinnernamespace;
  • 4.嵌套命名空间访问 : 需要使用两个域作用符进行访问 , 格式是 “外层命名空间::内层命名空间::内层命名空间定义的方法或变量名称” ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//没有声明命名空间 : 嵌套的命名空间调用 , 需要使用两个域作用符访问最内层命名空间中定义的方法 
	mynamespace::myinnernamespace::say_hi_inner(); 
  • 5.不声明命名空间的访问方式 : 此时就需要完整的使用两个域作用符访问内层命名空间中的方法或变量 , 代码如上面的代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//没有声明命名空间 : 嵌套的命名空间调用 , 需要使用两个域作用符访问最内层命名空间中定义的方法 
	mynamespace::myinnernamespace::say_hi_inner(); 
  • 6.声明外层命名空间的访问方式 : 此时可以不使用外层的命名空间名称 , 直接使用 “内层命名空间名称::方法名()” 访问内层命名空间中定义的方法 ;
    • ① 省略外层命名空间 : 只声明了外层命名空间 , 这里就可以省略上面的外层命名空间 ;
    • ② 不能省略内层命名空间 : 内层的命名空间不能省略 , 因为没有声明内部命名空间 ;
    • ③ 域作用符个数 : 需要一个域作用符访问内层命名空间中的方法 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//只声明了外层命名空间 , 这里就可以省略上面的外层命名空间 , 
	//但是内层的命名空间不能省略 , 因为没有声明内部命名空间, 
	//需要一个域作用符访问内层命名空间中的方法
	myinnernamespace::say_hi_inner();
  • 7.声明内层命名空间的访问方式 : 如果内层的命名空间被声明 , 那么可以不使用域作用符 , 直接访问内层命名空间中的方法 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//声明内层命名空间 : 如果声明了 内层的命名空间 , 可以调用内层命名空间中定义的 say_hi_inner() 方法
	say_hi_inner();
  • 8.嵌套命名空间代码示例 : ① 命名空间定义 , ② 命名空间声明 , ③ 命名空间调用 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//命名空间定义 : 自定义命名空间
namespace mynamespace {

	//调用时 需要调用 mynamespace::say_hi() 方法进行调用
	void say_hi() {
		//注意 : 下面的 cout 和 endl 定义在 std 命名空间中
		//如果没有声明 using namespace std; , 就必须使用域作用符号 "::" 才能访问
		//域作用符格式 : 命名空间::调用内容
		std::cout << "自定义命名空间 mynamespace say_hi() 方法 : Hi!" << std::endl;
	}

	//嵌套的命名空间需要调用 mynamespace::myinnernamespace::say_hi() 才能调用该方法
	namespace myinnernamespace {
		void say_hi_inner() {
			//注意 : 下面的 cout 和 endl 定义在 std 命名空间中
			//如果没有声明 using namespace std; , 就必须使用域作用符号 "::" 才能访问
			//域作用符格式 : 命名空间::调用内容
			std::cout << "自定义嵌套的命名空间 myinnernamespace say_hi_inner() 方法 : Hi Inner!" << std::endl;
		}
	}
}

//声明自定义的命名空间 , 声明 外层命名空间 , 
//可以直接调用 say_hi() 方法 ; 
//调用内层的 say_hi_inner() 方法需要使用 myinnernamespace::say_hi_inner() 进行调用
using namespace mynamespace;

//声明内层的命名空间 , 需要使用 外层命名空间::内层命名空间 进行声明
//这样就可以直接调用内层命名空间的 say_hi_inner() 方法了
using namespace mynamespace::myinnernamespace;

//下面是方法中的代码

	//没有声明命名空间 : 嵌套的命名空间调用 , 需要使用两个域作用符访问最内层命名空间中定义的方法 
	mynamespace::myinnernamespace::say_hi_inner(); 

	//只声明了外层命名空间 , 这里就可以省略上面的外层命名空间 , 
	//但是内层的命名空间不能省略 , 因为没有声明内部命名空间, 
	//需要一个域作用符访问内层命名空间中的方法
	myinnernamespace::say_hi_inner();

	//声明内层命名空间 : 如果声明了 内层的命名空间 , 可以调用内层命名空间中定义的 say_hi_inner() 方法
	say_hi_inner();
  • 9.执行结果 :
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
自定义嵌套的命名空间 myinnernamespace say_hi_inner() 方法 : Hi Inner!
自定义嵌套的命名空间 myinnernamespace say_hi_inner() 方法 : Hi Inner!
自定义嵌套的命名空间 myinnernamespace say_hi_inner() 方法 : Hi Inner!
域作用符

域作用符 :

  • 1.域作用符的作用 : 主要有两个作用 ;
    • ① 访问命名空间 : 一个是访问命名空间中的变量和方法 ;
    • ② 访问类成员 : 另一个是调用类中的方法 或 成员变量 ;

上述访问命名空间中的方法已经展示过了 , 下面介绍下访问类成员变量 ;

  • 2.定义类中的成员变量 : 该变量定义在类中 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//类的成员变量
int a_int = 888;
  • 3.在方法中定义一个同名的成员变量 : 注意类中的成员变量与方法中的局部变量赋值不同 , 用于区分两个变量 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//方法中的局部变量
	int a_int = 999;
  • 4.使用域作用符访问类成员变量 : 访问类中的变量格式为 “::变量名” , 如 ::a_int ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//域作用符 :: 作用
	//① 调用命名空间中的方法 或 变量
	//② 调用类中的方法 或 成员变量 , ::变量名称 可以访问类中的成员变量

	//方法中的局部变量
	int a_int = 999;
	//域作用符作用
	std::cout << "类中的成员变量 ::a_int : " << ::a_int << " 方法中的局部变量 a_int : " << a_int << std::endl;
  • 5.代码示例 :
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//类的成员变量
int a_int = 888;

//下面是方法中的代码
	//域作用符 :: 作用
	//① 调用命名空间中的方法 或 变量
	//② 调用类中的方法 或 成员变量 , ::变量名称 可以访问类中的成员变量

	//方法中的局部变量
	int a_int = 999;
	//域作用符作用
	std::cout << "类中的成员变量 ::a_int : " << ::a_int << " 方法中的局部变量 a_int : " << a_int << std::endl;
  • 6.执行结果 :
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
类中的成员变量 ::a_int : 888 方法中的局部变量 a_int : 999

命名空间 与 include 区别

在 C++ 代码中 , 经常遇到 #include "c_extern.h"using namespace std; 代码 , 两种方式都可以声明可使用的若干变量和方法 ;

  • include 作用 : 将包含的文件 在编译时 拷贝到 这个文件中 , 如上面 #include "c_extern.h" , 在编译时就将 c_extern.h 头文件中的内容 , 全部拷贝到本文件中 使用 #include "c_extern.h" 的位置 ;
  • 命名空间的作用 : 表明后面所有的代码都使用这个命名空间 , 如果调用命名空间中的方法, 就会去对应的命名空间中查找对应方法;

函数完全重复的情况 : 如果出现两个函数 , 其 ① 函数名 ② 参数个数 ③ 参数顺序 ④ 返回值 完全重复 , 这样就会造成冲突 ; 命名空间作用 : 命名空间就是避免出现上述函数完全重复的情况 , 可以将重复的函数定义在命名空间中 , 这样就能区分两个完全相同的函数 ;


命名空间定义与使用完整代码

代码中包含部分 C/C++ 兼容 , C/C++ 字符串 相关代码 , 属于上一篇博客遗留, 可忽略 , 只看命名空间相关的代码 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 001_CMake_1.cpp: 定义应用程序的入口点。
//

#include "001_CMake_1.h"
#include "c_extern.h"

//命名空间定义 : 自定义命名空间
namespace mynamespace {

	//调用时 需要调用 mynamespace::say_hi() 方法进行调用
	void say_hi() {
		//注意 : 下面的 cout 和 endl 定义在 std 命名空间中
		//如果没有声明 using namespace std; , 就必须使用域作用符号 "::" 才能访问
		//域作用符格式 : 命名空间::调用内容
		std::cout << "自定义命名空间 mynamespace say_hi() 方法 : Hi!" << std::endl;
	}

	//嵌套的命名空间需要调用 mynamespace::myinnernamespace::say_hi() 才能调用该方法
	namespace myinnernamespace {
		void say_hi_inner() {
			//注意 : 下面的 cout 和 endl 定义在 std 命名空间中
			//如果没有声明 using namespace std; , 就必须使用域作用符号 "::" 才能访问
			//域作用符格式 : 命名空间::调用内容
			std::cout << "自定义嵌套的命名空间 myinnernamespace say_hi_inner() 方法 : Hi Inner!" << std::endl;
		}
	}
}

using namespace std;

//声明自定义的命名空间 , 声明 外层命名空间 , 
//可以直接调用 say_hi() 方法 ; 
//调用内层的 say_hi_inner() 方法需要使用 myinnernamespace::say_hi_inner() 进行调用
using namespace mynamespace;

//声明内层的命名空间 , 需要使用 外层命名空间::内层命名空间 进行声明
//这样就可以直接调用内层命名空间的 say_hi_inner() 方法了
using namespace mynamespace::myinnernamespace;

//类的成员变量
int a_int = 888;


//定义方法接收 int& 引用类型变量
//并在方法中修改该变量的值
void quote(int& b) {
	b = 888;
}

int main()
{
	cout << "Hello CMake。" << endl;

	//1. C C++ 兼容
	//博客地址 : https://hanshuliang.blog.csdn.net/article/details/98840708
	//调用 c_extern.h 头文件中定义的方法
	//该方法定义在了 C 语言文件中
	add(1, 2);


	//2. 引用数据类型
	//博客地址 : https://hanshuliang.blog.csdn.net/article/details/99239635
	//代码 展示 流程 : 
	//① 定义 普通 类型 变量
	int a = 8;
	//② 定义 引用类型变量, 格式 : 类型名称& 变量名 = 对应类型变量名称 ;
	int& b = a;
	//③ 调用函数传入引用类型参数 : 将引用类型传给接收引用类型的方法
	quote(b);
	//④ 打印引用数据类型的修改结果 , 结果是 b 被修改成了 888
	cout << b << endl;

	//引用数据类型定义与使用 : 
	// ① 引用数据类型定义 : 类型名称& 变量名 = 对应类型变量名称 ;
	// ② 引用数据类型的使用方法 : 直接当做原来的变量使用即可, 可以替换原来变量的位置使用

	//引用类型解析 : 
	// ① int& 是引用数据类型 , b 是 a 的引用 
	// ② 分配一块内存存放 int 类型数据 8 , 将该内存赋予一个别名 a
	// ③ 同时又给该内存赋予另外一个别名 b 


	//3. 字符串使用

	//C 字符串
	//博客地址 : https://hanshuliang.blog.csdn.net/article/details/99295034

	//C 字符串 表示方法 : 
	// ① 字符数组 : 本质是 字符 数组 char[] , 这里注意字符数组要以 NULL 或 '\0' 结尾; 
	char string_c[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
	// ② 指针 : 使用指针形式表示字符串 , 默认末尾增加 '\0' ;
	char* string_c_p = "hello";

	//字符串打印 : 
	// ① 打印字符串 , cout 后的 << 后可以打印 字符串 , 也可以打印变量
	// ② 输出 cout << 字符串或变量1 << 字符串或变量2 ... << endl 可以拼接 输出信息
	cout << "string_c : " << string_c << endl;
	cout << "string_c_p : " << string_c_p << endl;

	//C 语言中的字符串操作
	//拷贝字符串 
	char string_c_copy_destination[6];
	char string_c_copy_source[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
	// ① 参数 : strcpy 方法是拷贝字符串的方法 , 第一个参数是目标字符串 , 第二个参数是源字符串
	// ② 作用 : 该方法是将 源字符串 拷贝到 目标字符串中
	strcpy(string_c_copy_destination, string_c_copy_source);
	// ③ 打印拷贝结果 : 
	cout << "string_c_copy_destination : " << string_c_copy_destination << endl;

	//拼接字符串 
	//① 定义目标字符串 : 拼接字符串的目标字符串的大小一定要大于等于要拼接的两个字符串大小之和, 否则会报错
	char string_c_cat_destination[50] = " cat dst ";
	char string_c_cat_source[] = " cat src ";
	//② 拼接字符串方法参数 : 第一个参数是目标字符串 , 第二个参数是源字符串
	//③ 目标字符串大小 : 注意 目标字符串的 大小一定要大于 两个字符串实际大小
	strcat(string_c_cat_destination, string_c_cat_source);
	//④ 打印字符串拼接结果 : 
	cout << "string_c_cat_destination : " << string_c_cat_destination << endl;


	//获取字符串长度
	//① 参数 : 传入要获取的字符串 , 该长度不含 '\0' 结尾标志
	//② 作用 : 获取实际的字符串长度 , 即自动识别 '\0' 位置 , 获取其长度 , 与所占用的内存大小无关
	char string_c_len[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
	char string_c_len2[20] = { 'h', 'e', 'l', 'l', 'o', '\0' };
	char * string_c_len3 = "hello";
	
	//① 字符数组长度 , 测量从开始到 '\0' 的长度, 不包括 '\0'
	int len1 = strlen(string_c_len);
	//② 指定大小的字符数组长度 , 结果不是指定的大小的值 , 获取的是实际字符串长度
	int len2 = strlen(string_c_len2);
	//③ 指针表示的字符串 , 其获取的大小是实际字符串大小, 不包含自动添加的 '\0' 
	int len3 = strlen(string_c_len3);
	//④ 打印 三个字符串大小
	cout << "len1 : " << len1
		<< " len2 : " << len2
		<< " len3 : " << len3
		<< endl;


	//字符串比较
	// ① 参数说明 : 参数是需要比较的两个字符串 , 第一个参数 str1 , 第二个参数 str2
	// ② 对比规则 : str1 和 str2 两个字符串 , 从左到右 逐个对比 ASCII 码 大小 ; 
	//		a. 如果 str1 等于 str2 , 返回 0; 
	//		b. 如果 str1 > str2 , 返回值 大于 0 ;
	//		c. 如果 str1 < str2 , 返回值 小于 0 ;

	//定义需要比较的字符串
	char* string_c_comp_1 = "Hello";
	char* string_c_comp_2 = "Hello";
	char* string_c_comp_3 = "hello";

	// ① 两个字符串相等
	int cmp_result_1_2 = strcmp(string_c_comp_1, string_c_comp_2);
	// ② "Hello" 字符串 (H 对应 ASCII 72) 小于 "hello" 字符串 (h 对应 ASCII 104) , 返回值 小于 0
	int cmp_result_1_3 = strcmp(string_c_comp_1, string_c_comp_3);
	// ③ "hello" 字符串 (h 对应 ASCII 104) 大于 "Hello" 字符串 (H 对应 ASCII 72) , 返回值 大于 0
	int cmp_result_3_1 = strcmp(string_c_comp_3, string_c_comp_1);

	//输出字符串对比结果
	cout << "cmp_result_1_2 : " << cmp_result_1_2 
		<< " cmp_result_1_3 : " << cmp_result_1_3
		<< " cmp_result_3_1 : " << cmp_result_3_1
		<< endl;


	//C++ 字符串
	//博客地址 : https://hanshuliang.blog.csdn.net/article/details/99336346


	// C++ string 类 : 该类定义在 iostream 头文件中
	//创建 string 类型对象有三种方法 : 
	//① 直接使用字符串赋值 
	//② 调用构造方法赋值 
	//③ 最后可以调用 new 为字符串分配一块内存

	//① 使用字符串赋值
	string string_c_plus_1 = " Hello ";

	//② 调用构造方法 初始化字符串
	string string_c_plus_2(string_c_plus_1);
	string string_c_plus_3(" World ");

	//上面的三种字符串不需要释放 , 因为其定义在栈内存中 , 下面使用 new 创建字符串的情况需要 delete 释放内存 ; 

	//③ 使用 new 申请的内存 , 需要使用 delete 释放
	string *string_c_plus_4 = new string(" New ");
	delete string_c_plus_4;

	//使用 new [] 申请的数组 , 需要使用 delete[] 释放
	//使用 malloc 申请的内存 , 需要使用 free 释放

	//C++ 字符串输出
	//字符串对象不能直接在 cout 中输出, cout << string string_c_plus_5 << endl; 是错误的
	//cout << string_c_plus_2 << endl;
	//要将 string 对象打印到控制台上, 需要将其转为 C 字符串 , char* 或 char[] 才能输出
	cout << string_c_plus_1.c_str() << endl;


	//C++ 字符串拼接
	//① "+" : 操作符重载 , 重新定义了 加号运算符的行为 , 这里加号可以实现字符串拼接 , 与 Java 类似
	//② 调用 string 对象的 append 方法 , 拼接字符串
	string string_c_plus_5 = string_c_plus_1 + string_c_plus_3;
	string string_c_plus_6 = string_c_plus_1.append( string_c_plus_3 );

	//输出拼接的字符串
	cout << string_c_plus_5.c_str() << endl;
	cout << string_c_plus_6.c_str() << endl;
	


	//获取 C++ 字符串长度 : 调用 string 对象的 size() 方法 , 获取字符串长度
	int string_c_plus_1_size = string_c_plus_1.size();
	cout << "string_c_plus_1_size : " << string_c_plus_1_size << endl;

	//判断 C++ 字符串是否为空 : 调用 string 对象的 empty() 方法 ; 
	bool string_c_plus_1_empty = string_c_plus_1.empty();
	cout << "string_c_plus_1_empty : " << string_c_plus_1_empty << endl;

	//使用 new 创建的对象 , 就不能使用 . 访问其方法和变量 , 需要使用 -> 符号进行访问 
	// -> 相当于 (*). 运算, 先读取指针内容 , 然后访问其方法或变量

	string* string_c_plus_7 = new string(" New String ");
	
	//① 获取字符串长度 : 
	int string_c_plus_7_size = string_c_plus_7->size();
	cout << "string_c_plus_7 : " << string_c_plus_7_size << endl;

	//② 判断字符串是否为空 : 
	bool string_c_plus_7_empty = string_c_plus_7->empty();
	cout << "string_c_plus_7_empty : " << string_c_plus_7_empty << endl;

	//释放堆内存
	delete string_c_plus_7;

	//使用指针的好处 : 
	// ① 如果在栈内存中使用 , 有作用域限制 , 出了栈内存 作用域 , 该对象就无效了 ; 
	// ② 指针 大小为 4 ( 32 位系统 ) 或 8 ( 64 位系统 ) 个字节 , 
	//	  其当做参数传递 比直接传递对象 ( 动辄几十上百字节甚至更高 ) 效率更高 


	//4. 命名空间
	//博客地址 : https://hanshuliang.blog.csdn.net/article/details/99406975
	// 命名空间 相当于 Java 中的 Package 包 , 
	//	上面的 cout endl string 等都定义在 std 命名空间中
	// 如果没有 using namespace std; 声明命名空间 , 
	//	那么必须使用域作用符 "::" ( 两个冒号 ) , 否则全都会报错
	std::cout << 
		"没有使用命名空间 需要使用 std::cout << ... << std::endl 打印" 
		<< std::endl;

	//没有声明命名空间 : 调用自定义的 mynamespace 命名空间中的 say_hi 方法 , 必须使用域作用符
	mynamespace::say_hi();

	//声明命名空间 : 如果声明了 外层的命名空间 , 可以调用外层命名空间中定义的 say_hi() 方法
	say_hi();

	//没有声明命名空间 : 嵌套的命名空间调用 , 需要使用两个域作用符访问最内层命名空间中定义的方法 
	mynamespace::myinnernamespace::say_hi_inner(); 

	//只声明了外层命名空间 , 这里就可以省略上面的外层命名空间 , 
	//但是内层的命名空间不能省略 , 因为没有声明内部命名空间, 
	//需要一个域作用符访问内层命名空间中的方法
	myinnernamespace::say_hi_inner();

	//声明内层命名空间 : 如果声明了 内层的命名空间 , 可以调用内层命名空间中定义的 say_hi_inner() 方法
	say_hi_inner();


	//域作用符 :: 作用
	//① 调用命名空间中的方法 或 变量
	//② 调用类中的方法 或 成员变量 , ::变量名称 可以访问类中的成员变量

	//方法中的局部变量
	int a_int = 999;
	//域作用符作用
	std::cout << "类中的成员变量 ::a_int : " << ::a_int << " 方法中的局部变量 a_int : " << a_int << std::endl;



	//include 与 命名空间 区别 : 
	// include 的作用 : 将包含的文件 在编译时 拷贝到 这个文件中 , 
	//		如上面 #include "c_extern.h" , 在编译时就将 c_extern.h 头文件中的内容 
	//		全部拷贝到本文件中 使用 #include "c_extern.h" 的位置 
	//命名空间的作用 : 表明后面所有的代码都使用这个命名空间 , 如果调用命名空间中的方法, 
	//		就会去对应的命名空间中查找对应方法; 

	//函数完全重复 : 如果 出现 两个函数 , 其 函数名 参数个数 参数顺序 返回值 完全重复 , 这样就会造成冲突 
	//命名空间作用 : 避免 出现 函数名称 参数及参数顺序 , 返回值 完全相同的情况 , 可以将重复的函数定义在命名空间中 , 这样就能区分两个完全相同的函数 

	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-08-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Oracle 审计失败的用户登陆(Oracle audit)
       对于在线交易系统,且Oracle用户在使用缺省的profile的情形下,多用户共享相同的数据库用户及密码,任意用户输入错误密码累计达到10次以上,其帐户会被自动锁定使得交易被迫临时终止将产生不小的损失。故有必要对那些失败的帐户登陆进行分析以预估是否存在恶意攻击等。Oracle提供了审计功能用于审计那些失败的Oracle用户登陆来进行风险评估。本文即是描述如何开启审计失败的用户登陆。本文不涉及审计的具体的描述信息,仅仅描述如何审计失败的用户登陆。详细完整的审计大家可以参考Oracle Database Security Guide。
Leshami
2018/08/13
1.8K0
等保测评2.0:Oracle安全审计
本篇文章主要说一说Oracle数据库安全审计控制点中b、c、d测评项的相关内容和理解,以及一些其它零碎的与等保相关的内容。
FB客服
2020/07/28
7.6K0
Oracle 10g安全加固(审计、监听密码)
Oracle 10g审计功能默认是关闭的。 需要注意开启审计功能必然会额外消耗一部分数据库性能,开启审计需要重启数据库生效。 具体的审计策略则需要根据项目实际要求自行配置。
Alfred Zhao
2019/05/24
9270
【DB笔试面试828】在Oracle中,什么是审计(Audit)?
审计(Audit)用于监视用户所执行的数据库操作,审计信息可存储于数据字典表,称为审计记录。审计记录存储在SYSTEM表空间中的SYS.AUD表中,可通过视图DBA_AUDIT_TRAIL查看。审计记录也可以存储在操作系统文件中(默认位置为ORACLE_BASE/admin/ORACLE_SID/adump/)。若审计表不存在,则可以通过脚本ORACLE_HOME/rdbms/admin/cataudit.sql来创建。
AiDBA宝典
2020/06/24
2.2K0
案例分享:关闭 Oracle 审计时遇到的 Bug 排查与解决
一重要的生产库长期以来就有各种问题,前段时间刚进行完 PSU190716 的更新,这两天查到发现审计功能对其性能有较大的影响,故客户要求关闭审计功能。我们便申请了三个小时的停机窗口,进行关闭审计的操作。心想改参数重启实例四十分钟就可以搞定的事,三个小时多多有余,因为数据量达五六十 T ,小伙伴都比较怕,只有我做了。以下涉及到实际的主机名、实例名均已替换为测试相关的,如不对应忽略即可。
JiekeXu之路
2020/05/12
1.9K0
由dual导致的一个潜在的监控问题(r7笔记第3天)
Oracle对于sys用户的审计是默认的操作,所以不管你开启了什么审计策略,sys的登录等操作都会记录下来,这也是Oracle的默认配置,可能他 们也没有料到有些应用可能把这个影响放大,毕竟频繁登录sys听起来是不现实的。但是放到自动化监控的部分,这个影响就会放大,可能有些功能还不够严谨, 存在一定的问题。 比如下面的这个场景,发现在审计目录下存在着一些细小的文件,生成时间也很紧凑,可见还是有一些操作很频繁的使用了sys,而且生成了意料之外的大批量审计日志文件。 $ ls -lrt|head -5 -rw
jeanron100
2018/03/16
6260
【常用命令】监视数据库的用户登录和注销会话信息
通过使用audit session whenever successful 命令,成功的连接会被审计。
SQLplusDB
2020/03/26
1.6K0
Oracle 主库rac + 备库rac 11.2.0.4的DG环境部署
各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~:
AiDBA宝典
2023/04/27
4.1K0
Oracle 主库rac + 备库rac 11.2.0.4的DG环境部署
Oracle告警日志里记录了“KILL SOFT -/-/-”会话被杀掉的信息
当由于空闲超时而手动或由PMON终止会话后手动执行alter system kill session时,将在警报日志中记录相关信息
AiDBA宝典
2023/09/08
5060
Oracle告警日志里记录了“KILL SOFT -/-/-”会话被杀掉的信息
手动清理Oracle审计记录
a、对于Oracle 11g,审计功能默认被开启,因此如果在必须启用的情况下应考虑性能影响; b、开启审计的情况下,建议将审计从system或sysaux表空间剥离,使用单独的表空间; c、对于历史审计日志的清除,应考虑清除期间所带来的性能影响; d、调用DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION这个过程已经开始了搬迁过程,如果审计日志很庞大,应考虑IO影响; e、审计日志的清除需要先设定归档,已归档的审计日志会被清理; f、也可以通过trunate table aud$ reuse storage以及deallocate非常规方式来处理。
Leshami
2018/08/13
1.7K0
EXP导出aud$报错EXP-00008,ORA-00904 解决
主题:EXP导出aud$报错EXP-00008,ORA-00904 解决 环境:Oracle 11.2.0.4 问题:在自己的测试环境,导出sys用户下的aud$表报错。
Alfred Zhao
2019/05/24
1.5K0
Oracle 常用命令大汇总
第一章:日志管理     1.forcing log switches     sql> alter system switch logfile;     2.forcing checkpoints     sql> alter system checkpoint;     3.adding online redo log groups     sql> alter database add logfile [group 4]     sql> ('/disk3/log4a.rdo','/di
阿新
2018/04/09
9430
2021年4月Oracle数据库补丁分析报告
编写此文档为了更好地指导Oracle补丁安装工作,细化工作任务,规范安装升级操作。
数据和云
2021/05/31
2.4K0
又一例SPFILE设置错误导致数据库无法启动
--========================================
Leshami
2018/08/07
7420
Oracle知识集锦:对Oracle数据库进行监控检查
execute dbbms_workload_repository.create_snapshot();
星哥玩云
2022/08/16
1.2K0
等保测评之Oracle关系型数据库安全加固实践指南
select ‘bgdrac’ database,t11.username,t11.default_tablespace tablespace_name,segment_size_in_GB,datafile_size_in_gb,tablespace_free_size_in_gb from (select username,default_tablespace from dba_users) t11 left join ( select nvl(t1.tablespace_name,t2.tablespace_name) tablespace_name,t1.size_in_GB datafile_size_in_GB,t2.size_in_GB segment_size_in_GB,t1.size_in_GB-t2.size_in_GB tablespace_free_size_in_GB from (select tablespace_name,sum(bytes)/1024/1024/1024 size_in_GB from dba_data_files group by tablespace_name) t1 full join (select tablespace_name,sum(bytes)/1024/1024/1024 size_in_GB from dba_segments group by tablespace_name) t2 on t2.tablespace_name=t1.tablespace_name) t22 on t22.tablespace_name=t11.default_tablespace where t11.default_tablespace<>’zlbfxt’;
全栈工程师修炼指南
2022/09/29
1.9K0
Oracle 10gR2 Dataguard搭建(非duplicate方式)
我的实验环境: 源生产库(主库): IP地址:192.168.1.30 Oracle 10.2.0.5 单实例
Alfred Zhao
2019/05/24
7460
单实例Primary快速搭建Standby RAC参考手册(19.16 ADG)
上述为这里我做为演示环境的基本规划。 本文作为step by step的快速指导手册,方便快速部署此类ADG环境。
Alfred Zhao
2023/03/06
4020
一线运维 DBA 五年经验常用 SQL 大全(二)
本文 SQL 及相关命令均是在运维工作中总结整理而成的,对于运维 DBA 来说可提高很大的工作效率,值得收藏。当然如果你全部能够背下来那就很牛逼了,如果不能,还是建议收藏下来慢慢看,每条 SQL 的使用频率都很高,肯定能够帮助到你。
JiekeXu之路
2021/03/15
9050
一线运维 DBA 五年经验常用 SQL 大全(二)
oracle11g dataguard安装实施
Oracle DataGuard 实施 1.环境准备 1.1 修改主备机hosts文件 vi /etc/hosts 128.160.11.84    wang 128.160.11.218  dg2 1.2 修改(添加)主备机listener.ora和tnsnames.ora文件 vi $ORACLE_HOME/network/admin/listener.ora SID_LIST_LISTENER =         (SID_LIST =           (SID_DESC =                 (SID_NAME = softdb)                 (ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1/)           )         ) LISTENER =   (DESCRIPTION_LIST =     (DESCRIPTION =       (ADDRESS = (PROTOCOL = TCP)(HOST = wang)(PORT = 1521))       (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))     )   ) ADR_BASE_LISTENER = /u01/app/oracle vi $ORACLE_HOME/network/admin/tnsnames.ora SOFTPRI =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = wang)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = softdb)     )   ) SOFTSTD =   (DESCRIPTION =     (ADDRESS = (PROTOCOL = TCP)(HOST = dg2)(PORT = 1521))     (CONNECT_DATA =       (SERVER = DEDICATED)       (SERVICE_NAME = softdb)     )   ) 1.3 确定主备机parameter/control/data/log/archivelog file 的路径 audit_file_dest='/u01/app/oracle/admin/softdb/adump' 1.4 设置主库强制写日志 SQL> select force_logging from v$database; FOR --- NO SQL> alter database force logging; Database altered. SQL> select force_logging from v$database; FOR --- YES 1.5 设置主库归档模式 SQL> archive log list; SQL> shutdown immediate; SQL> startup mount; SQL> alter database archivelog; SQL> alter database open; SQL> archive log list; Database log mode              Archive Mode Automatic archival             Enabled Archive destination            /u01/app/oracle/product/11.2.0/db_1//dbs/arch Oldest online log sequence     175 Next log sequence to archive   177 Current log sequence           177 2. 产生用于建立Standby库的全备份集及控制文件 2.1 创建并修改主库参数文件pfile SQL> shutdown immediate; SQL> create pfile from spfile; 修改initsoftdb.ora vi $ORACLE_HOME/db
吹水老王
2022/05/17
8120
推荐阅读
相关推荐
Oracle 审计失败的用户登陆(Oracle audit)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档