【问题标题】:C++ Referencing extern const within a namespaceC++ 在命名空间中引用外部常量
【发布时间】:2017-02-07 02:15:59
【问题描述】:

我正在尝试在我的项目的其他地方使用在 TaxConstants.hpp 命名空间 TAXCONSTANTS 中声明的常量 int SIZE。当我尝试编译时,我在所有引用 SIZE 的地方都得到“未定义的对 'SIZE' 的引用。

文件 TaxConstants.hpp

#ifndef TaxConstants_hpp
#define TaxConstants_hpp


namespace TAXCONSTANTS
{
     extern const int SIZE = 4; // I have tried with and without extern
}

#endif //TAXCONSTANTS_HPP

main.cpp

#include <iostream>
#include "TaxConstants.hpp"
using namespace std;
using namespace TAXCONSTANTS;

int main()
{
extern const int SIZE;

// This is a struct defined in another file. It is a sample of my use for SIZE. I left out the #include above to simplify things. 
taxPayer payers[SIZE];  

//More code

return 0;
}

附加信息:这是一个学校项目,我的老师要求在命名空间 TAXCONSTANTS 中的文件 TaxConstants.hpp 中声明常量。

总共有 5 个文件,包含我的函数的文件对 SIZE 错误具有相同的未定义引用。

我花了几个小时查找有关 extern 函数和命名空间的类似解释,但大多数建议首先反对这样做,而是提供另一种解决方案。我很遗憾不能使用它们。人们遇到的其他错误是得到了我没有的“多重装饰”。

编辑

请参阅下面的 Brians 解释以获得更详细的信息。

我需要做的是定义

const int SIZE = 4;

在命名空间 TAXCONSTANTS 的 TaxConstants.hpp 文件中。

然后删除 '外部常量 int SIZE;' 从我的主文件中引用 SIZE by TAXCONSTANTS::SIZE 在我想使用大小的任何地方。

这是我完全忘记的基本命名空间。

【问题讨论】:

标签: c++ namespaces constants extern


【解决方案1】:

如果您定义SIZE 没有 extern 关键字,它将具有内部链接,因为它是const。您可以在main.cpp 中将其称为TAXCONSTANTS::SIZE。建议这样做,因为编译器将能够在使用 SIZE 的任何位置内联该值。

如果你定义SIZE with extern 关键字,它将有外部链接,它不应该在标题中,除非你想要多个定义错误。您应该在 .cpp 文件中定义它,该文件将链接到程序的其余部分。在这种情况下,整个程序中只有一份SIZE。您应该避免这种方法(更喜欢没有extern 的方法)除非出于某种原因,您实际上需要在整个程序中只有一个SIZE 的副本。

在这两种情况下,SIZE 都将是 TAXCONSTANTS 命名空间的成员。

您在main 中重新声明SIZE 的尝试并没有达到您的预期!下面是main里面的:

extern const int SIZE;

其实有在全局命名空间中声明SIZE的效果。由于全局命名空间中没有SIZE 的定义,因此在链接时会出现未定义的引用错误。引用TAXCONSTANTS 中定义的SIZE 变量不是正确的方法。

【讨论】:

  • 谢谢,我在返回这里之前就想通了。您写的是,我做错了,应该改用 TAXCONSTANTS::SIZE。
【解决方案2】:

整个方法存在多个问题。

  1. 你的

    extern const int SIZE;
    

    main 中是来自全局命名空间::SIZEconst int 对象SIZE 的声明。这个SIZE 与你的TAXCONSTANTS::SIZE 完全无关。这样的全局::SIZE 对象未在您的程序中定义,这就是您收到“未定义引用”错误的原因。

    由于您已经在头文件中声明了TAXCONSTANTS::SIZE,因此您无需在main 中再次重新声明SIZE。你为什么要这样做?

    只需从main 中删除声明,然后从TAXCONSTANTSusing namespace TAXCONSTANTS 或通过指定限定名称TAXCONSTANTS::SIZE 使用SIZE

  2. 你在头文件中的声明实际上是一个定义。将此头文件包含在多个翻译单元中会导致另一个错误:同一个对象的多个定义具有外部链接。

    如果你想声明一个全局常量对象,你必须在头文件中保留一个非定义的声明

    namespace TAXCONSTANTS
    {
      extern const int SIZE; // declaration, not definition
    }
    

    并将定义移动到实现文件之一

    namespace TAXCONSTANTS
    {
      extern const int SIZE = 4; // definition
    }
    
  3. 但是,您似乎打算将此常量用作积分常量表达式(作为数组声明中的数组大小)。在没有初始化器的情况下声明的 extern const int 常量将无法用于此目的。

    忘记extern,在头文件中声明一个带有内部链接的普通常量

    namespace TAXCONSTANTS
    {
      const int SIZE = 4; // definition with internal linkage
    }
    

    然后在需要的地方使用

    using namespace TAXCONSTANTS;
    
    int main()
    {
      taxPayer payers[SIZE];  
      ...
    }
    

    // no 'using namespace TAXCONSTANTS;'
    
    int main()
    {
      taxPayer payers[TAXCONSTANTS::SIZE];  
      ...
    }
    

【讨论】:

  • 谢谢你,我应该像你提到的那样写 TAXCONSTANTS::SIZE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 2017-10-05
相关资源
最近更新 更多