C++ 在命名空间中引用 extern const

C++ Referencing extern const within a namespace

我试图在我项目的其他地方使用 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 函数和名称空间的类似解释,但大多数建议首先反对这样做并提供另一种解决方案。不幸的是,我不能使用它们。人们遇到的其他错误是得到了我没有的“多个装饰”。

编辑

有关详细信息,请参阅下面的 Brian 解释。

我需要做的是定义

const int SIZE = 4;

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

然后删除 'extern const int SIZE;' 从我的主文件中取而代之的是 TAXCONSTANTS::SIZE 在我想使用 size.

的任何地方引用 SIZE

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

整个方法存在多个问题。

  1. 你的

    extern const int SIZE;
    

    in main 是来自全局命名空间 - ::SIZEconst int 对象 SIZE 的声明。这个SIZE和你的TAXCONSTANTS::SIZE完全没有关系。这样的全局 ::SIZE 对象没有在你的程序中定义,这就是你得到 "undefined reference" 错误的原因。

    因为你已经在头文件中声明了TAXCONSTANTS::SIZE,你不需要在main中再次声明SIZE。你为什么要这样做?

    只需从 main 中删除声明并通过 using namespace TAXCONSTANTS 或通过指定限定名称 TAXCONSTANTS::SIZE.[=33 使用 TAXCONSTANTS 中的 SIZE =]

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

    如果你想声明一个全局常量对象,你必须在头文件中只保留一个non-defining声明

    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];  
      ...
    }
    

如果您定义 SIZE 而没有 extern 关键字,它将具有内部 linkage,因为它是 const .您可以在 main.cpp 中将其称为 TAXCONSTANTS::SIZE。这是推荐的,因为编译器将能够在任何使用 SIZE 的地方内联该值。

如果您定义 SIZE extern 关键字,它将具有外部 linkage 并且它不应该在 header,除非你想要多个定义错误。您应该改为在 .cpp 文件中定义它,该文件将被 link 编辑到程序的其余部分中。在这种情况下,整个程序中将只有一份SIZE。你应该避免这种方法(更喜欢没有 extern 的方法) 除非 由于某种原因你实际上只需要在整个程序中有一个 SIZE 的副本。

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

您在 main 中重新声明 SIZE 的尝试与您认为的不同! main内的以下内容:

extern const int SIZE;

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