我正在努力处理遗留代码(计划重构,但我现在需要使用它),它的devicedrivers被设计为接受其构造函数的(argc, argv)
参数。我必须使用的基类,现在我不能改变它,看起来像这样:
class LegacyDriver
{
public:
LegacyDriver(int argc, char** argv)
{
if (argc < 3)
{
throw std::runtime_error("nope");
}
// some logic with the arguments interpretation
int var1 = std::stoi(argv[1]);
int var2 = std::stoi(argv[2]);
std::cout << "config: " << var1 << ", " << var2 << "\n";
// etc ...
}
virtual ~LegacyDriver() = default;
// + some public interfaces, not important ...
};
然后我的新驱动程序必须扩展这个类,需要以某种方式将argc, argv
参数传递给基类。到目前为止,我的同事们只是沿着:
class MyNewDriver: public LegacyDriver
{
public:
MyNewDriver(int argc, char** argv): LegacyDriver(argc, argv)
{}
~MyNewDriver() override = default;
};
但是这种设计显然是不可持续的(例如,很难测试),我想至少为新驱动程序提供一个有意义的构造函数,比如:
MyNewDriver(int param1, int param2): LegacyDriver(somehowTransformThemIntoArgcArgv)
{}
我不能为此使用额外的MyNewDriver
私有字段,因为父类必须在此之前构造。我想到了这样的hack,在全局范围内使用字符串和向量:
namespace {
std::string hackyProgramName = "Driver";
std::string hackyVar1;
std::string hackyVar2;
std::vector<const char*> hackyArgv;
auto constructArgv = [](int var1, int var2)
{
hackyVar1 = std::to_string(var1);
hackyVar2 = std::to_string(var2);
hackyArgv = std::vector<const char*>({hackyProgramName.c_str(), hackyVar1.c_str(), hackyVar2.c_str()});
return const_cast<char**>(hackyArgv.data());
};
}
class MyNewDriver: public LegacyDriver
{
public:
MyNewDriver(int argc, char** argv): LegacyDriver(argc, argv)
{}
MyNewDriver(int param1, int param2): LegacyDriver(3, constructArgv(param1, param2))
{}
~MyNewDriver() override = default;
};
但是它看起来太丑了,argv
vector在我的驱动程序的每个新示例中都无效。
有没有更好的办法?最好是单个lambda。
2条答案
按热度按时间envsm3lx1#
因为你必须维护一个有效的
argv
数组,并且在构造LegacyDriver
之前要做的动作,所以你可以继承一个类。yqyhoc1h2#
当你移动一个向量时,指向它的指针仍然有效。所以你可以先构造argv vector,然后将它移动到一个成员: