C ++命名空间成员在不同文件中的访问方式如何?如何实现“命名空间标准”?

如何解决C ++命名空间成员在不同文件中的访问方式如何?如何实现“命名空间标准”?

| 我在sample.h中声明了以下名称空间
// namespace with identifier
namespace N1
{
    int b = 80;
}
sample1.cpp使用上面的名称空间声明
#include <iostream>
#include \"sample.h\"

using namespace std;
using namespace N1;

int main(void)
{
    cout << \"b (in main) = \" << b << endl;
      foo(); //written in sample2.cpp
      return 0;
}
sample2.cpp也使用sample.h中声明的名称空间
#include <iostream>
#include \"sample.h\"

using namespace std;
using namespace N1;

void foo(void)
{
    cout << \"b = \" << b << endl;
}
当我编译时,出现以下错误
$> g++ sample1.cpp sample2.cpp
/tmp/ccB25lEF.o:(.data+0x0): multiple definition of `N1::b\'
/tmp/cchLecEj.o:(.data+0x0): first defined here
让我知道如何解决以及如何实现“命名空间标准”来避免此问题?     

解决方法

包含保护仅在编译时有效,但错误发生在链接时。这是因为sample.h包含在两个编译单元中,并且在两个编译单元中都创建了变量
N1::b
。 如果您确实想要一个变量(不是
const
),则必须在标头中将其声明为
extern
,并在单独的编译单元中为其创建存储位置:
// sample.h
#ifndef N1
#define N1
namespace N1 {
    extern int b;
}
#endif

// sample.cpp
#include \"sample.h\"
namespace N1 {
    int b = 80;
}
    ,这不是ѭ8守卫的问题。 在头文件中使用ѭ6表示:
//sample.h
namespace N1
{
    extern int b; //extern is MUST!

    //DONT WRITE : extern int b = 80;
}
然后在.cpp文件中将其定义为:
//sample.cpp
namespace N1
{
    int b = 80;  //initialization should be here
}
    ,是否只是在sample.h文件中丢失了ifdef或pragma的情况?     ,每次将#sample.h包含在.cpp模块中时,都会为b创建一个新的链接器记录,从而为link [1]提供多个定义。 应该在sample.cpp或其他地方定义int,并简单地在sample.h中将int b终止。 [1]一些链接器将忽略此链接,您将可以链接OK,但是大多数情况下,它将生成错误。     ,您的问题是,您在一个头文件中定义了一个具有外部链接的对象,该文件包含在两个单独的编译单元中。该问题与命名空间本身无关。 一种解决方案是使头文件仅包含声明(例如,参见下文),然后将定义放在单个源文件上。
// sample.h
namespace N1
{
    extern int b;
}

// sample.cc
namespace N1
{
    int b = 80;
}
另一个解决方案是赋予对象内部链接,尽管这将意味着您有多个名为“ 13”的对象,但这可能不是问题。例如,如果假定
b
是常数,则这将起作用,因为默认情况下
const
个对象具有内部链接。
// sample.h
namespace N1
{
    const int b = 80;
}
    ,如果您只想定义一个常量,请尝试以下方法:
namespace N1
{
    enum MyEnum
    {
      b = 80
    };
}
对于几乎所有.h文件,包含保护都是一个好主意,但是在这里,它们可能不是您的问题。最重要的一个定义规则有两个主要部分:第一个部分说每个符号只能在每个翻译单元(通常是.cpp文件)中定义一次。这就是include防护的作用:它们防止将标头包含两次,这将导致在同一翻译单元(= .cpp文件)中多次定义一个符号(如N :: b)。 但是,这还不是全部。某些符号(例如类,非内联函数和某些变量定义)对于整个程序只能声明一次。这不是没有道理的:假设您允许在一个转换单元中将名为MyInt的int值定义为40,在另一个转换单元中将其定义为80:编译器将如何知道要使用哪个值?当然,您可以在每个程序中多次声明这样的符号(但每个翻译单元只能声明一次)-否则它们只能在声明它们的翻译单元中使用。但是不能在一个以上的翻译单元中定义它们。 使用枚举是避免在您的情况下必须分开声明和定义的一种简便方法(因为枚举不受“一个定义规则”的第二版约束),但是如果您确实需要(非常量)全局变量
int
类型,您可以通过以下方式实现: 样本
namespace N1
{
    // The extern keyword tells the compiler that this is is only
    // a declaration and the variable is defined elsewhere.
    extern int b;
}
sample1.cpp
#include \"sample.h\"

namespace N1
{
    // This is the definition!
    int b = 5;
}

void foo()
{
    using namespace std;
    cout<<N1:b<<endl;
}
sample2.cpp
#include \"sample.h\"

// No need to define N1::b,since it was already defined in sample1.cpp.

void bar()
{
    using namespace std;
    cout<<N1:b<<endl;
}
    ,该程序包含变量
N1::b
的两个定义,而必须完全是一个。该变量必须在带有“ 6”的标头中声明,并且只能在一个源文件中定义。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-