c++ - C++ 头文件中的声明和初始化过多

标签 c++ header-files

我有一个很大的 Constants.h 文件,其中声明和初始化了大约 200 个变量(主要是数组)。我正在使用命名空间。

方法一:

//Constants.h

#ifndef CONSTANTS_H_
#define CONSTANTS_H_

namespace LibConstants
{
    const int a = 12;
    const std::string theme[2]; = {"themeA", "themeB"};
    const int arr[2] = {1, 2};
    // and around 200 more declarations with initialization
}
#endif

这个.h文件几乎在每个.cpp文件中都是#include,但每次只使用非常少的变量,如LibConstants::theme[0].

我的方法工作正常,但是它不会分配不必要的内存吗? 我是否应该遵循该方法,仅在 .h 文件中定义变量并在 .cpp 中初始化?

如下面的代码所示: 方法2:

//Constants.h

#ifndef CONSTANTS_H_
#define CONSTANTS_H_

namespace LibConstants {

    std::string getMyTheme(int arg);
    std::string getMyThemeName(int arg);

    const int a;
    const std::string theme[2];
    const int arr[2];
    // and around 200 more declarations with initialisation
};
#endif

在cpp文件中初始化

//Constants.cpp

#include LibConstants.h
using namespace LibConstants {
     std::string getMyTheme(int arg) {
         theme[2] = {"themeA", "themeB"};
         return theme[arg];
     }
     std::string getMyThemeName(int arg) {
         ...
     }
}

像使用它

//HelloWorld.cpp

#include Constants.h
int main() {
     //METHOD 1:
     std::string a = LibConstants::theme[0]; // arg=0 is dynamic and is being read from localStorage in my case. 
     //METHOD 2:
     std::string a = LibConstants::getMyTheme(0); //Here also arg=0 is dynamic.
     ...
}

这里,除了在头文件中声明为 const std::string st[2]; 的数组之外,不会为不需要的变量分配不必要的内存。

这里“arg=0”是运行时参与。如果某个变量不依赖于运行时而仅依赖于编译时,在这种情况下它将简单地替换相应 .cpp 文件中占位符的值,这是否重要?

有错误的地方请指正。

最佳答案

std::string 为例。考虑一下,

namespace Constants {
const std::string str = "A not very short string";
}

str 是一个类类型,它有一个构造函数,并且它必须分配内存来存储其内容(除非在其实现中使用短字符串优化。即使在这种情况下,它也只适用于“短字符串”)。它被声明为命名空间范围变量。所以程序必须在启动时构造这个变量。每个声明了该变量的程序都需要分配内存并初始化其内容。这是您可能不想要的开销,具体取决于它对您的性能的影响程度。

另一方面,如果你有,

const std::string &str()
{
     const static std::string s = "A not very short string";

     return s;
}

现在,您有了一个静态局部变量。它将在函数的第一个入口处初始化。并且它只会被初始化一次。如果 str 从未被调用,则它根本不会被初始化。

但是,请注意,字符串文字“A not very Short string”仍然会占用一些内存。其存储位置和方式由实现定义。通常在数据段,影响通常很小。

与类类型相反。最好在 header 中定义基本类型,尤其是整型。

例如,

namespace Constants {
constexpr int x = 10;
}

优化编译器很可能根本不存储变量x及其内容10。相反,只要使用 x,它就会被 10 替换,并且在某些情况下,会被编码到指令操作码(所谓的立即操作数)中。当然,这又是一个实现细节。并且这种优化不能依赖于所有编译器。如果您采用 x 的地址或使用其他 ODR,编译器将被迫为该变量腾出空间。但底线是,在 header 中声明此常量不太可能比在外部源文件中定义它更糟糕。

关于c++ - C++ 头文件中的声明和初始化过多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41109886/

相关文章:

C++:命名空间——如何在头文件和源文件中正确使用?

c++ - Windows下线程创建和终止需要多长时间?

c++ - MPL pos 是一个未记录的元函数吗?

c - 头文件 dh.h 中缺少定义(openssl 1.1.0f)

c++ - 您可以在 C++ header 中包含 .cu 扩展 header 吗?

c++主文件混淆

C++ 错误,可能来自 .h 文件,不确定

c++ - 我可以在不计算的情况下从 Windows RECT 结构访问宽度和高度吗?

c++ - std::map operator [] - 未定义的行为?

c++ - 包含 std::string 常量的类