[C++ Memory Station] Namespace

Insert image description here


Insert image description here

Namespace concept

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存 在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

When many people first come into contact with C++, they know that printing a line hello worldis written like this:

#include
using namespace std;
int main()
{
cout << “hello world” << endl;
}

But if I ask you what iostream and namespace std are, and what role they play in this line of code, many beginners basically can't answer it. They only know how to write it, but they don't know the meaning.

So now start to understand the concept of namespace
大家都知道C++是在c语言基础上建立的,c语言很多地方存在很多缺陷的,C++就创建了一个命名空间的概念来弥补这一缺陷
这一缺陷是什么呢?创建一个全局变量 int rand = 0 ,你只引入了头文件 <stdio.h> ,利用printf打印出rand,不会产生任何问题。可当你再引用了 <stdlib.h> ,再次运行程序就会出现问题
Insert image description here
这里报错,显示rand重定义,这里的问题叫做命名冲突,因为 stdlib.h 这个库里面已经定义了rand,且定义成的一个函数,而我们这个全局变量rand是int类型的元素,系统在识别这个rand的时候就会找到两个rand,它不知道去打印哪一个,当然这里刚好rand在库里面是个函数 且与%d发生冲突,显示两个错误

In C language, the simplest and crudest way to solve this problem is to change the variable name to prevent naming conflicts with variables of the same name in the library. This can certainly solve the problem, but if you need to work in groups to complete a project in a team, The individual variables of each group are the same. What to do at this time? You can't directly quarrel with each other. This will greatly reduce work efficiency and affect the team atmosphere, so this method is obviously not advisable.

Insert image description here
Since C language cannot solve this problem, C++ has been proposed 命名空间to solve it .
A keyword is introduced here namespace. Its function is to create a domain to protect the created rand variable. The following is the code implementation.

namespace Yuan
{
    
    
	int rand = 0;
}
int main()
{
    
    
	printf("%d\n", rand);
}

namespaceThe following name can be whatever you want. As long as you remember it,
there will be no naming conflict. What is printed in main is the rand in the library function (to be precise, it accesses the global domain to find rand), not Yuan.
If you want to print the rand inside Yuan, you need to add it in front of rand .Yuan::

namespace Yuan
{
    
    
	int rand = 0;
}
int main()
{
    
    
	printf("%d\n", Yuan::rand);
}

namespaceWhat is created is a local domain named Yuan. Here we need to review the global variables and local variables in the C language.

int i = 0;
int main()
{
    
    
	int i = 1;
	printf("%d", i);
}

Now I ask you a question, is the i printed here 0 or 1?

The answer is 1. One is satisfied here 就近原则. The printed result is 1. Here is the local variable i in the local domain that is directly accessed.

But what if you want to access the global variable i in the local domain?

Need to add in front of i::

int i = 0;
int main()
{
    
    
	int i = 1;
	printf("%d\n", ::i);
	printf("%d\n", i);
}

::It is called a domain operator, and its function is to specify which domain to find the i. ::The left side here is blank, which means to find it in the global domain.

Insert image description here

Therefore, the problem of naming conflicts can be easily solved with the concept of namespace. There are three groups ABC. All the variables written by each group are stored in their own defined namespaces, and the namespaces are respectively transferred to nodeA nodeB nodeC. Even if there are the same variables in their respective namespaces, they will not be received. any impact

Namespace definition

1. Normal namespace definition

Variables, functions, types, etc. can be defined in the namespace.

namespace Yuan
{
    
    
	int rand = 0;
	void func()
	{
    
    
		printf("func()\n");
	}

	struct TreeNode
	{
    
    
		struct TreeNode* left;
		struct TreeNode* right;
		int val;
	};
}

int main()
{
    
    
	printf("%p\n", rand);
	printf("%p\n", Yuan::rand);

	Yuan::func();

	struct Yuan::TreeNode node;

	return 0;
}

2. Namespaces can be nested

Namespaces can be nested, just like loop statements

namespace sql
{
    
    
	int a = 0;
	namespace Yuan
	{
    
    
		int rand = 0;
		void func()
		{
    
    
			printf("func()\n");
		}

		struct TreeNode
		{
    
    
			struct TreeNode* left;
			struct TreeNode* right;
			int val;
		};
	}
}


int main()
{
    
    
	printf("%p\n", rand);
	printf("%p\n", sql::Yuan::rand);

	sql::Yuan::func();

	struct sql::Yuan::TreeNode node;

	return 0;
}

3. Multiple namespaces with the same name are allowed to exist in the same project. The compiler will eventually synthesize them into the same namespace.

How to understand this? For example, in a project we added Stack.h (stack), Stack.cpp (stack), Queue.h (queue), Queue.cpp (queue), which contain many variables and types. , functions, etc. Now we need to put them into a namespace. We will worry about naming conflicts. How to deal with it?
Define a namespace each time Yuan in these four files, and put everything in the file Put them into namespaces. These four namespaces have the same name but are not in the same file. The compiler will automatically merge them into one namespace, so you don’t have to worry about naming conflicts.

namespace Yuan
{
    
    
	typedef int STDataType;
	typedef struct Stack
	{
    
    
		STDataType* a;
		int top;		// 栈顶的位置
		int capacity;	// 容量
	}ST;
}

#include "Stack.h"//栈
#include "Queue.h"//队列

int main()
{
    
    
	Yuan::ST st;
	Yuan::StackInit(&st);

	Yuan::Queue q;
	Yuan::QueueInit(&q);
}

Use of namespaces

1. Add namespace name and scope qualifier

int main()
{
    
    
    printf("%d\n", Yuan::a);
    return 0;  
}

We have already introduced the use of namespaces through domain scopes. This is also the most basic and simple way to use namespaces. However, this method becomes a bit cumbersome when namespaces are used a lot. Maybe it is not available here. Adding domain operators, but not adding them there, resulted in a lot of bugs, so there are three ways:

2. Use using to introduce a member of the namespace

using Yuan::b;
int main()
{
    
    
    printf("%d\n", Yuan::a);
    printf("%d\n", b);
    return 0;  
}

3. Use using namespace namespace name introduction

using namespce N;
int main()
{
    
    
    printf("%d\n", Yuan::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;  
}

4. Use using namespace std C++ standard library namespace introduction

The first two are relatively conservative. This one is very bold and directly expands the entire C++ standard library. Although it avoids certain conflicts to a large extent, there may be a risk of conflicts if all are expanded in this way, so it is not recommended to directly expand all of them. Use, if you want to use it, you should write it like this

#include<iostream>
//using namespace std
int main()
{
    
    
	std::cout << "hello world" << std::endl;
	return 0;
}

Insert image description here

Guess you like

Origin blog.csdn.net/cdtu_mid/article/details/132322303