管理命令行参数
Managing command line arguments
正在更新一些旧代码,原作者决定所有的命令行参数变量都应该是全局变量。从测试和开发的角度来看,这显然使事情更具挑战性。
我的问题是如何最好地管理所有类需要使用的命令行参数(例如跟踪标志/调试标志)。一位同事建议至少将变量包装在名称空间中,但这似乎还不够。我考虑过单例或静态类,只提供getter,但这似乎不是很优雅。另一方面,这似乎比必须传递5个配置选项给每个需要知道是否调试和少数其他选项设置的类要好。
全局变量的最大问题是,在函数内部更改它们往往会产生意想不到的副作用,从而引入bug。然而,在命令行参数的情况下,就正在运行的进程而言,它们本质上是常量。唯一阻止您声明它们的是const
,它们需要在您开始解析命令行时分配。
我建议创建一些机制,允许您在开始时初始化参数,但随后防止程序的任何部分更改它们。这将有效地避免全局变量通常会引入的任何缺点。
一种方法可能是ProgramArguments
类/结构,其const成员在构造函数中通过解析命令行初始化。你可以这样写:
std::unique_ptr<ProgramArguments const> g_program_arguments;
int main(int argc, char* argv[])
{
g_program_arguments.reset(new ProgramArguments(argc, argv));
if(g_program_arguments->verbose)
std::cout << "verbose!" << std::endl;
// ...
return 0;
}
这不会阻止你改变指针指向不同的ProgramArguments实例。另一种方法可能是为了初始化目的暂时抛弃constness:
struct ProgramArguments {
ProgramArguments() {}
bool verbose;
};
ProgramArguments const g_program_arguments;
void init_program_arguments(int argc, char* argv[])
{
ProgramArguments& program_arguments = const_cast<ProgramArguments&>(g_program_arguments);
program_arguments.verbose = true;
}
int main(int argc, char* argv[])
{
init_program_arguments(argc, argv);
if(g_program_arguments.verbose)
std::cout << "verbose!" << std::endl;
return 0;
}
这取决于我们正在讨论的全局变量的数量。就我个人而言,我认为有一些全局变量是很好的,比如调试标志和单例日志管理器。
如果你真的想遵守书本上的OOP原则,那么你就必须把函数或对象需要的所有东西作为参数传递。从不访问全局状态。正如您所提到的,向每个函数传递大量公共参数很快就会变得无聊,因此有一种模式可以帮助您缓解这种情况,即上下文对象。
相关文章:
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- 使用 C++ 将命令行参数拆分为参数/向量
- 如何在OMNET++中添加专门的命令行参数?
- 如何在不传递命令行参数的情况下在 c++ 中设置环境变量
- atoi() 在应用于大型命令行参数时会产生不正确的值
- 是否可以在命令行中将输入参数传递给可执行文件
- 命令行参数,cant 或两个变量
- 在 Windows 中使用 boost::p rogram_options 从命令行参数读取 Unicode 字符
- 如何在 Android/NDK 上将命令行参数从 gradlew.bat 传递到 Clang
- 编写一个将 LLVM IR 文件作为命令行参数的程序
- 通过命令行参数获取llvm ir文件时面临问题
- 有没有办法根据命令行参数定义数组大小?运行时与编译时实例化?
- 从命令行获取参数时出现问题
- 如何在不使用文件扩展名的情况下使用命令行参数打开C++中的文本文件?
- 命令行参数在不到 3 个 LOC 中 int?
- 在命令行参数中使用引号
- 使用参数 + stdout + stderr 从命令行调用 MFC 应用程序
- 在VS2013中使用devenv (C++)传递命令行参数argv
- 二进制数据作为命令行参数