【发布时间】:2021-09-28 21:01:47
【问题描述】:
由于我正在处理的项目的硬件版本不同,有两个版本的 c++ 类控制硬件。应该使用的类的版本应该在运行时确定,因此实例化需要动态发生。两个类的函数名和返回类型总是相同的。
我应该如何创建这样一个类?我已经阅读了多态性和类继承,并尝试编写以下代码,但它不起作用。我觉得我正在朝着正确的方向前进,但缺乏完全解决这个问题的经验。我下面的实现不会动态创建类,我认为这是导致我的问题的原因。
提前感谢您的帮助。
#include <string>
#include <iostream>
class HWVer1 {
private:
std::string _msg;
public:
HWVer1(std::string x): _msg(x) {}
void do_something(){ std::cout<<"hello from HWVer1: "<<_msg <<"\n"; }
};
class HWVer2 {
private:
std::string _msg;
public:
HWVer2(std::string x): _msg(x) {}
void do_something(){ std::cout<<"hello from HWVer2: "<<_msg <<"\n"; }
};
class Wrapper1: public HWVer1 { public: Wrapper1(std::string x):HWVer1(x){} };
class Wrapper2: public HWVer2 { public: Wrapper2(std::string x):HWVer2(x){} };
int main(int argc, char ** argv){
int HW_ver = 2;
if (HW_ver == 1){
Wrapper1 HW("Wrap1");
}
else if (HW_ver == 2){
Wrapper2 HW("Wrap2");
}
HW.do_something(); // error: ‘HW’ was not declared in this scope --> does not work because reference to HW is destroyed after scope of if /else if statement ends
}
注意:HW.do_something() 不在 if 语句中的原因是因为在 HWVer1/HWVer2 中找到的函数在整个代码的许多地方都使用过。这个练习的重点是避免在每次访问硬件类之前使用 if/else if 语句。我只是想改变一点开销,让其余的代码保持原样。为此,声明的硬件类需要可全局访问,因为这是当前实现硬件类的各个版本的方式。
更新:
我已经解决了我的问题。以下似乎有效:
#include <string>
#include <iostream>
class HWVerBase
{
public:
virtual void do_something() = 0;
virtual void do_something_else() = 0;
};
class HWVer1: public HWVerBase
{
public:
void do_something(void){
std::cout << "I am in HWVer1!" << std::endl;
}
void do_something_else(void){
std::cout << "I am doing something else in HWVer1!" << std::endl;
}
};
class HWVer2: public HWVerBase
{
public:
void do_something(void){
std::cout << "I am in HWVer2!" << std::endl;
}
void do_something_else(void){
std::cout << "I am doing something else in HWVer2!" << std::endl;
}
};
int main(int argc, char ** argv){
int HW_ver = 1;
HWVerBase* ptrHWVer;
if (HW_ver == 1){
ptrHWVer = new HWVer1;
}
else if (HW_ver == 2){
ptrHWVer = new HWVer2;
}
ptrHWVer->do_something();
ptrHWVer->do_something_else();
delete ptrHWVer;
}
输出:
我在HWVer1! 我正在 HWVer1 中做其他事情!
这种方法的唯一“缺点”是所有定义为虚拟的函数也必须在 HWVer1 和 HWVer2 类中定义。我认为如果能够按照 MSalters 下面的建议使用 std::shared_ptr ,这可能是可以避免的。但不幸的是,我正在编译的系统无法访问此版本的 C++。所以这个(相当基本的)方法现在就可以了。感谢所有做出贡献的人。
【问题讨论】:
-
将
HW.do_something();移动到if内? -
您不能有一个可以直接存储
Wrapper1或Wrapper2的对象,因为Wrapper1和Wrapper2之间没有关系。如果它们具有共同的基本类型,则可以使用多态性。你仍然可以通过额外的步骤来实现这一点,比如使用std::variant。 -
@appleapple 我更新了我的问题,最后进行了编辑,以解释为什么我想避免这种情况
-
您是否考虑过只使用像
using my_type = Wrapper1;这样的类型别名?您是否需要根据运行时信息传播不同的类型?显示的示例没有,但这可能只是由于示例过于简单。 -
看看奇怪的递归模板模式(crtp)
标签: c++ class inheritance