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;
}
浙公网安备 33010602011771号