怎么解决c++域名空间冲突
发布网友
发布时间:2023-05-05 11:26
我来回答
共1个回答
热心网友
时间:2023-11-10 11:27
你没有理解C++的namespace。如果你熟悉java的话,你可以这样理解,java中用包机制取代了所谓的命名空间。在java中一般是一个类一个文件的(原则上说多个类放一个文件下也没问题),然后相同功能的一组类文件组合成了一个包。
在C++中,namespace就相当于java中的包,单纯的头文件是不需要命名空间的,如果你想把多个类、辅助函数等等组合成一个整体,就用namespace。
命名空间是防止名称碰撞的机制,比如我有一个class A,你也有一个class A,那么我们在同一个程序下的话到底是用你的A还是我的A?在C++中就这样用I::A、Y::A,而java中则是I.A,Y.A
不需要.h的头文件,是C++的标准头文件,里面都包含了namespace std,如果是标准出现前的C++头文件,如<iostream.h>这些都不包含namespace,那个时候还没这个概念。新的头文件是标准出现后重写的,防止命名碰撞问题(VC++6.0是标准之前的编译器,允许使用旧版的头文件,但这些都不包含namespace,而新编译器都不再使用带.h的C++标准头文件)如果是C的头文件,如<stdio.h>就不包含namespace,C++重写的C的头文件都包含std,名称为<cXXX>,如<cstdio>
至于谁包涵谁的问题就很难说清楚了,因为namespace虽然一般都是用在头文件中的(规范使用是在头文件中),但是一个头文件不一定需要namespace,而且一个namespace可以包涵多个不同头文件。我举个例子:
1
2
3
4
5
6
7
8
9
//file1.h
namespace A{
class B{};
}
//file2.h
namespace A{
class C{};
}
//class B、C 都属于一个namespace A中,但却分属于不同的头文件
你最后提到mport相当于include,你可以这样认为,但又有不同。首先从2者的实现机制来看,import是引入一个包或者引入包下的某个类文件,include只引入头文件(java中没有头文件,所以是实现和声明一起引入的,C++中实现和头文件是拆开的,include只包含声明部分,实现是由链接器最后链接组成的)
其次 java中的 import 既包含了包的引入,又开放了包的命名。比如import java.swing.*; 你用JFrame类时就不用写javax.swing.Frame了,只要写JFrame;但C++中include只包含了声明的引入,要想开放命名空间需要using指令,如using namespace std 或using std::cout,然后就能直接写 cout了,否则每次都要写std::cout
至于你说的std::相当于System.out.,是完全不对的。因为System是属于java.lang这个包下的一个类,而out是类下的一个成员对象。java.lang.才相当于std::
而cout和print()是有本质区别的,这个你可以看下《C++ primer》或者《C++程序设计语言(十周年纪念版)》(这2本书都对namespace有清楚的解释,建议看一下),我简单解释下吧,以下是简化版本的cout实现:
1
2
3
4
5
6
7
8
9
10
namespace std{
……
class ostream{
……
ostream& operator<<(ostream&,const string&);
……
}
……
ostream cout;
}
热心网友
时间:2023-11-10 11:27
你没有理解C++的namespace。如果你熟悉java的话,你可以这样理解,java中用包机制取代了所谓的命名空间。在java中一般是一个类一个文件的(原则上说多个类放一个文件下也没问题),然后相同功能的一组类文件组合成了一个包。
在C++中,namespace就相当于java中的包,单纯的头文件是不需要命名空间的,如果你想把多个类、辅助函数等等组合成一个整体,就用namespace。
命名空间是防止名称碰撞的机制,比如我有一个class A,你也有一个class A,那么我们在同一个程序下的话到底是用你的A还是我的A?在C++中就这样用I::A、Y::A,而java中则是I.A,Y.A
不需要.h的头文件,是C++的标准头文件,里面都包含了namespace std,如果是标准出现前的C++头文件,如<iostream.h>这些都不包含namespace,那个时候还没这个概念。新的头文件是标准出现后重写的,防止命名碰撞问题(VC++6.0是标准之前的编译器,允许使用旧版的头文件,但这些都不包含namespace,而新编译器都不再使用带.h的C++标准头文件)如果是C的头文件,如<stdio.h>就不包含namespace,C++重写的C的头文件都包含std,名称为<cXXX>,如<cstdio>
至于谁包涵谁的问题就很难说清楚了,因为namespace虽然一般都是用在头文件中的(规范使用是在头文件中),但是一个头文件不一定需要namespace,而且一个namespace可以包涵多个不同头文件。我举个例子:
1
2
3
4
5
6
7
8
9
//file1.h
namespace A{
class B{};
}
//file2.h
namespace A{
class C{};
}
//class B、C 都属于一个namespace A中,但却分属于不同的头文件
你最后提到mport相当于include,你可以这样认为,但又有不同。首先从2者的实现机制来看,import是引入一个包或者引入包下的某个类文件,include只引入头文件(java中没有头文件,所以是实现和声明一起引入的,C++中实现和头文件是拆开的,include只包含声明部分,实现是由链接器最后链接组成的)
其次 java中的 import 既包含了包的引入,又开放了包的命名。比如import java.swing.*; 你用JFrame类时就不用写javax.swing.Frame了,只要写JFrame;但C++中include只包含了声明的引入,要想开放命名空间需要using指令,如using namespace std 或using std::cout,然后就能直接写 cout了,否则每次都要写std::cout
至于你说的std::相当于System.out.,是完全不对的。因为System是属于java.lang这个包下的一个类,而out是类下的一个成员对象。java.lang.才相当于std::
而cout和print()是有本质区别的,这个你可以看下《C++ primer》或者《C++程序设计语言(十周年纪念版)》(这2本书都对namespace有清楚的解释,建议看一下),我简单解释下吧,以下是简化版本的cout实现:
1
2
3
4
5
6
7
8
9
10
namespace std{
……
class ostream{
……
ostream& operator<<(ostream&,const string&);
……
}
……
ostream cout;
}