草庐IT

C++篇 ---- 命名空间namespace

青山与你 2024-06-04 原文

由于在c语言中在定义时可能会出现重命名现象,造成空间冲突,c语言中有命名冲突:1 和库冲突。2 互相之间的冲突,变量命名冲突。所以c++中就有了对其改进的关键字namespace,针对重定义,解决空间冲突。

文章目录


命名空间namespace

以下是c语言实现的代码

#include<stdio.h>
#include<stdlib.h>

int rand = 1;

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


这里会报错是由于变量rand与库函数中的rand相同,导致了命名冲突

如何解决命名冲突?

使用namespace。

此时修改rand的域,用域对rand进行隔离,同一个域中不能定义相同变量,因此将其隔离到其它域中

  • 类域
  • 命名空间域
  • 局部域
  • 全局域

而此时要将其修改到命名空间域中去。

当一个程序中一个变量在局部和全局并且命名空间都有创建时,编译器优先搜索访问的是局部,再全局如果命名空间域展开(展开命名空间是指编译器是否会到命名空间搜索) 的话再命名空间,否则是不会搜索访问命名空间的

展开命名空间(using naespace std):

  1. 命名空间直接展开有风险,定义和库重合会报错
  2. 建议项目中不要去展开,在我们日常用的时候展开没什么大问题
  3. 推荐指定访问,指定展开c++常用的,如 using namespace cout,using namespace cin,using namespace endl
//全局域
int a = 1;

//命名空间域
namespace zzm
{
	int a = 2;
}


int main()
{
	//局部域
	int a = 0;
	printf("%d\n", a);
	return 0;
}

无局部时

当变量只在命名空间域有定义时

此时并没有将命名空间展开using或者加域作用限定符::,就相当于编译器不知道这个命名空间,所以也就搜索不到变量a,而此时可以加域作用限定符或者展开命名空间


是指在这个命名空间里去搜索找变量a,zzm::指定到命名空间zzm中搜索,其左边zzm的为命名空间的名字,

如果左边的为空白 :: 就表示在全局域去搜索查找

其实在编译器中它在定义或者使用时会向前面查找,搜索是否有相同或者存在,而在搜索时又先从局部域开始,局部域没有全局域,如果都没有是不会默认到命名空间域搜索的,只有将其展开using或者使用域限定符::指定访问命名空间域

namespace zzm
{
	int a = 2;
}

using namespace zzm;

int main()
{
	//局部域
	//int a = 0;//将局部屏蔽
	printf("%d\n", a);
	return 0;
}

但是将其命名空间展开之后有不可与全局同时用,因为此时编译器并不确定是命名空间域的还是全局域的

不展开:相同变量在不同域中可以同时存在,只是需要使用域限定符搜索指定命名空间
命名空间展开:也就将封在命名空间里面的内容暴露在全局域了,就如上面,此时编译器也不确定访问谁

而由开始引出的变量命名与库中相同时,也就有了解决方法。将这个变量定义到命名空间域中,直接在命名空间搜索访问

#include<stdio.h>
#include<stdlib.h>

namespace lsy
{
	int rand = 1;
}

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


此时也就解决了命名冲突问题了。

命名空间里面不仅仅可以定义变量还可以定义函数,结构体任意类型。且也可以嵌套命名空间

namespace n1
{
    int a = 0;
    int b;
    int Add(int left, int right)
    {
        return left + right;
    }

    namespace n2
    {
        int a = 1;
        int c;
        int d;
        int Sub(int left, int right)
        {
            return left - right;
        }
    }
}

int main()
{
    printf("%d\n", n1::a);
    printf("%d\n", n1::n2::a);//不过嵌套在搜索时先搜索外边的然后再搜索里面嵌套的
    //就像盒子都要先打开外边的叭
    printf("%d\n", n1::Add(1, 2));
    //
    return 0;
}

而c++的库和stl都封在一个命名空间std中,c++库中的东西都在std中,像cout,cin,endl啊这些常见的都是命名空间std中的


可以说namespace是解决c语言的命名冲突而出现的

有关C++篇 ---- 命名空间namespace的更多相关文章

  1. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  2. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  3. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  4. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  5. ruby - 使用 Nokogiri 和 Ruby 命名元素 "text" - 2

    我在尝试使用Nokogiri构建XML文档时遇到了一个小问题。我想将我的元素之一称为“文本”(请参阅​​下面粘贴代码的最底部)。通常,要创建一个新元素,我会执行类似以下的操作xml.text--但它似乎是.text是Nokogiri已经用来做其他事情的方法。因此,当我写这行时xml.textNokogiri没有创建名为的新元素但只是写了意味着成为元素内容的文本。我怎样才能让Nokogiri实际制作一个名为的元素??builder=Nokogiri::XML::Builder.newdo|xml|xml.TEI("xmlns"=>"http://www.tei-c.org/ns/1.0"

  6. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

  7. ruby-on-rails - Ruby/Rails 命名约定 - 2

    如果我生成一个名为"product"的脚手架,当我使用它们编写我的应用程序时,它们之间有什么区别?@products,@product,@Product,@Products,产品,Product、product和products(我很确定这些并没有全部用到,但它至少应该让我知道我在做什么'指的是)。对于@/capitalization/plurality的每个组合的含义,我似乎找不到简单的解释。将不胜感激。 最佳答案 你可以阅读Rubystyleguide和Railsstyleguide,您会得到问题的答案。

  8. ruby-on-rails - 具有管理 namespace 的 Rails 3 中的 I18n - 2

    我正在根据Rails指南的建议开发Rails应用程序,以创建包含翻译的文件夹树和文件。我的文件夹树与此类似:|-defaults|---es.rb|---en.rb|-models|---book|-----es.rb|-----en.rb|-views|---defaults|-----es.rb|-----en.rb|---books|-----es.rb|-----en.rb|---users|-----es.rb|-----en.rb|---navigation|-----es.rb|-----en.rbconfig/locales/views/books/en.yml中的内容

  9. ruby 认为我在引用一个顶级常量,即使我指定了完整的命名空间 - 2

    在我的应用程序中我有classUserincludeUser::FooendUser::Foo定义在app/models/user/foo.rb现在我正在使用一个定义了自己的Foo类的库。我收到此错误:warning:toplevelconstantFooreferencedbyUser::FooUser仅引用具有完整路径的Foo,User::Foo,而Foo实际上从来没有指的是Foo。这是怎么回事?更新:才想起我之前遇到过同样的问题,在问题1中看到这里:HowdoIrefertoasubmodule's"fullpath"inruby? 最佳答案

  10. Ruby 命名空间与类还是模块? - 2

    考虑Ruby类Foo::Bar。惯例是将“Foo”命名空间作为一个模块,但它也可以很容易地作为一个类:moduleFoo;classBar;end;end对比:classFoo;classBar;end;end在第二种情况下,Bar不是Foo的内部类,它只是在Foo的单例上定义的另一个常量。在这两种情况下,父类(superclass)都是Object并且它们只包含Kernel模块。它们的祖先链是相同的。因此,除了您可以根据其类使用Foo进行的操作(如果是类则实例化,如果是模块则扩展/包含),命名空间的性质是否对有任何影响酒吧?是否有令人信服的理由选择其中一个名称间距而不是另一个?我看到

随机推荐