1、为什么需要命名空间
命名空间是ANSI C++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。
使用命名空间解决名字冲突
但是,一个大型的应用软件,往往不是由一个人独立完成的,而是由若干不同的人合作完成的,不同的人分别完成不同的部分,最后组成一个完整的程序。
假如不同的人分别定义了类,放在了不同的文件中,在主函数的文件中需要使用这些类时,就用#include指令将这些头文件包含进来。由于头文件室友不同的人设计的,有可能在不同头文件中用了相同的名字来命名所定义的类或函数。这样,程序中就会出现名字冲突。
//PeopleA.h namespace PeopleA class Student {public: Student(int n, char s, string name) { //..... } private: int num; string name; char sex; }; int fun(int a, int b) { return a + b; } //PeopleB.h namespace PeopleB class Student { public: Student(int n, char s, string name) { //..... } private: int num; char sex; string name; }; int fun(int a, int b) { return a + b; } #include <iostream> #include "People A.h" #include "People B.h" int main() { PeopleA::Student stdu1(101, 18, "wang"); cout << PeopleA::fun(5, 3) << endl; PeopleB::Student stdu1(101, 18, "wang"); cout << PeopleB::fun(5, 3) << endl; return 0; }
2、什么是命名空间
所谓命名空间,实际上就是一个由程序设计者命名的内存区域。
程序设计者可以根据需要制定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。如:
namespace AA { int a; double b; }
namespace是定义命名空间锁必须写的关键字,AA是自己制定的命名空间的名字。
如果在程序中要使用a和b,必须加上命名空间名和作用域分辨符::,如AA::a,AA::b,这种用法称为命名空间限定。
命名空间的作用是建立一些互相分隔的作用域,把一些全局实体分隔开来,以免产生名字冲突。
3 线程间数据传输
是因为定义的是全局变量,全局变量是存在静态区域
全局变量是函数外面定义的,不是主函数内部的开头。
namespace 只是起了个命名空间。
CMakeLists.txt
cmake_minimum_required(VERSION 3.10) # Set the project name project(GlobalMatrixExample) # Find Eigen package find_package(Eigen3 3.3 REQUIRED) # Find pthread package find_package(Threads REQUIRED) # Add executable add_executable(global_matrix_example main.cpp) # Link Eigen3 and pthreads to the target target_link_libraries(global_matrix_example Eigen3::Eigen Threads::Threads)
main.cpp
#include <iostream> #include <Eigen/Dense> #include <thread> #include <mutex> /* 多线程是可以访问全局变量的,只要注意互锁 1 配合namespace能够清楚区分这是哪个全局变量 namespace 用于组织和管理代码的作用域,使得不同部分的代码能够清晰地分隔和访问共享的数据或功能。 指针用于直接操作和访问内存中的数据,允许动态内存分配和传递数据的引用。 namespace 通过定义全局变量来实现数据共享,这些变量可以在整个程序中访问,但它们的访问和修改需要保证线程安全。 指针通过传递内存地址来实现数据共享,可以在多个线程或函数之间共享和修改数据,指针操作本身并不保证线程安全,必须通过额外的机制(如互斥量)来保护数据的访问。 static全局变量与普通的全局变量有什么区别 ? 全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。 全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。 这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。 static全局变量只初使化一次,防止在其他文件单元中被引用; */ // 全局变量-而非主函数中开头定义的主函数内部全局变量 namespace MyNamespace { // 全局变量 Eigen::Matrix4d globalMatrix; double globalValue = 0.0; std::mutex matrixMutex; // 用于保护 globalMatrix 的互斥锁 } // 修改矩阵的线程函数 void modifyMatrix(int threadId) { std::lock_guard<std::mutex> lock(MyNamespace::matrixMutex); // 锁定互斥锁 MyNamespace::globalMatrix(0, threadId) = threadId; // 修改矩阵中的一个元素 MyNamespace::globalValue += threadId * 1.0; std::cout << "Thread " << threadId << " modified matrix:\n" << MyNamespace::globalMatrix << " \n updated globalValue to " << MyNamespace::globalValue << std::endl; } int main() { // 初始化矩阵 MyNamespace::globalMatrix.setZero(); // 创建多个线程 std::thread t1(modifyMatrix, 1); std::thread t2(modifyMatrix, 2); std::thread t3(modifyMatrix, 3); // 等待所有线程完成 t1.join(); t2.join(); t3.join(); // 输出最终矩阵 std::cout << "Final matrix:\n" << MyNamespace::globalMatrix << " \n Main thread final globalValue: " << MyNamespace::globalValue << std::endl; return 0; }