我有一个很大的文件,Constants.h
其中声明和初始化了约200个变量(主要是数组)。我正在使用名称空间。
方法1:
//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
文件#include
几乎存在于每个.cpp
文件中,但是每次仅使用非常小的变量,例如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"
仍然会占用一些内存。实现定义在何处以及如何存储。通常在数据段中,并且影响通常很小。
与类类型相反。最好在标头中定义基本类型,尤其是整数类型。
例如,
namespace Constants {
constexpr int x = 10;
}
一个优化的编译器很可能根本不存储该变量x
及其内容10
。取而代之的是,无论在何处x
使用它,都将由替换10
,并且在某些情况下,将其编码为指令操作码(即所谓的立即操作数)。当然,这又是一个实现细节。而且,并非所有编译器都依赖这种优化。而且,如果您使用x
的地址或其他方式使用ODR,则无论如何,编译器都将被迫为该变量腾出空间。但最重要的是,通过在标头中声明此常量,而不是在外部源文件中定义常量,您不太可能会变得更糟。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句