为什么要使用<;切德尔>;而不是<;标题h>;? 我一直认为,如果你写的代码代码包含< /COD>(其中代码>页眉是标准的C++头,像Stdio/StdLIb/string),则代码< > >包含,但被封装到 STD命名空间中。那么该代码段是如何编译的(g++4.7.3) #包括 int main() { malloc(1); 返回0; }
如果标准C函数仍然在全局命名空间中,那么为什么要包含为什么要使用<;切德尔>;而不是<;标题h>;? 我一直认为,如果你写的代码代码包含< /COD>(其中代码>页眉是标准的C++头,像Stdio/StdLIb/string),则代码< > >包含,但被封装到 STD命名空间中。那么该代码段是如何编译的(g++4.7.3) #包括 int main() { malloc(1); 返回0; },c++,namespaces,header-files,C++,Namespaces,Header Files,如果标准C函数仍然在全局命名空间中,那么为什么要包含(而不是)呢 第二个问题是,我应该怎么做才能从全局命名空间中获取这些函数(同时使用C++头)?例如,我不希望malloc位于全局命名空间中,因为我有一个主分配:编写自己的内存分配器(特别是malloc和free函数),我将编译到动态库中,并使用LD\u PRELOAD插入任何程序 那么该代码段是如何编译的(g++4.7.3) 因为C++11标准的17.6.1.2/4规定: […]是的 未指定这些名称是否首先在全局命名空间范围内声明,然后注入 通
(而不是
)呢
第二个问题是,我应该怎么做才能从全局命名空间中获取这些函数(同时使用C++头)?例如,我不希望
malloc
位于全局命名空间中,因为我有一个主分配:编写自己的内存分配器(特别是malloc
和free
函数),我将编译到动态库中,并使用LD\u PRELOAD
插入任何程序
那么该代码段是如何编译的(g++4.7.3)
因为C++11标准的17.6.1.2/4规定:
[…]是的
未指定这些名称是否首先在全局命名空间范围内声明,然后注入
通过显式使用声明(7.3.3)进入命名空间std
因此,允许实现在全局命名空间中定义这些实体
如果标准C函数仍将在全局命名空间中,那么为什么要包含then(而不是)
首先,作为一种好的风格。包含
可以确保所有实体都在全局名称空间中定义,而包含
可以确保这些实体在您想要的地方(在std
名称空间中),并且具有可能的(但不确定的)属性这些名称也可能出现在全局命名空间中,这是一个不必要的缺点
< >我应该怎样才能从全局命名空间中获得这些函数(同时使用C++头)?< /p>
不幸的是,您无法从实体所在的命名空间中获取实体。但是你可以做的(除了在你的实现中诅咒)是为了避免使用标准的C函数,而更喜欢使用C++标准库的函数。它们保证存在于std
名称空间中
因此,例如,如果必须执行低级内存管理,请使用
new
操作符而不是malloc
。此外,请注意强调“必须”:大多数情况下,您应该使用RAII包装,如智能指针或标准容器,以避免必须处理低级内存管理、新建
和删除
。因为,不幸的是,实现允许名称位于std::
名称空间之外,也可以要求名称位于名称空间之内。@juanchopanza但是如果我们允许标准头混乱全局名称空间,那么使用名称空间std
有什么意义呢?@karlicoss确实如此!这就是为什么我认为它是“不幸”的原因。它只适用于来自标准C库的名称。所有标准的C++函数和类型都只在gcc
或vim
或其他任何程序)将使用内存分配器。我只能在该赋值中使用非常低级的内存抽象,如mmap
系统调用。@karlicoss:我不知道为什么不能使用new
操作符;特别是我不确定我是否理解这一部分:“*我必须编写内存分配器,其他程序(二进制文件,如gcc或vim或其他什么)将使用*”。但是,我不需要理解,只要你知道你在做什么;)无论如何,这个故事的寓意是:您不能将实体从其声明的命名空间中取出,但您应该希望您的实现将在std
命名空间中声明它们。如果没有。。。好吧,至少你做了你的部分,包括了正确的标题。因为new
和delete
仍然是这个家庭作业的高级内存抽象。嗯,我必须实现一个内存管理库(使用malloc
,free
,calloc
,等等),基本上,我必须实现我自己。然后我将运行类似于LD\u PRELOAD=myallocator的程序。因此一些程序
和该程序将使用我的内存分配器,而不是g++
@karlicoss提供的内存分配器:好的,谢谢你的澄清
#include <cstdlib>
int main()
{
malloc(1);
return 0;
}