C++ 使用多组方法实现设计类[c+;+;]
我正在处理一个现有项目,该项目有一个类,我需要一个备用成员函数定义。我不想修改现有的成员函数或它们的签名,只想修改一个备用定义,它必须在运行时根据某个xml文件进行选择(编译时标志不是首选)。 我是C++新手,所以这可能是个愚蠢的问题。 请建议设计指南,这样我就不必更改和测试现有的代码库,只需插入我的实现 示例C++ 使用多组方法实现设计类[c+;+;],c++,design-patterns,C++,Design Patterns,我正在处理一个现有项目,该项目有一个类,我需要一个备用成员函数定义。我不想修改现有的成员函数或它们的签名,只想修改一个备用定义,它必须在运行时根据某个xml文件进行选择(编译时标志不是首选)。 我是C++新手,所以这可能是个愚蠢的问题。 请建议设计指南,这样我就不必更改和测试现有的代码库,只需插入我的实现 示例 class ABC{ public: int operate(int, int); } //Assume below method to be existing implementa
class ABC{
public:
int operate(int, int);
}
//Assume below method to be existing implementation
ABC::operate(int op1, int op2)
{
return op1+ op2; //add
}
//Alternate desired implementation
ABC::operate(int op1, int op2)
{
return op1 * op2; //multiply
}
理想情况下,我希望上面是运行时选择,但如果这是唯一的方法,则可能会落在编译时。请注意这个关于名称隐藏在继承中的线程
当派生类使用与基类中相同的名称实现非虚拟方法时,基类中的方法将隐藏,并且只有派生方法可以通过静态类型派生的对象使用
我给你的建议是实施类似于
class ABC{
public:
int operate(int, int);
};
//Assume below method to be existing implementation
ABC::operate(int op1, int op2)
{
return op1+ op2; //add
}
现在,对于您的扩展功能,从ABC派生(旁注:继承或组合是另一个讨论,请在google上阅读)
现在,无论您在哪里需要新功能,都可以将调用对象的静态类型更改为派生
,然后将调用派生的操作
如果可以将ABC的
operate
签名更改为虚拟int-operate(int,int),则更符合逻辑的解决方案是可能的
,则可能发生polimorphism,通过任何地方的引用类型访问operate
将调用属于调用对象的动态类型的operate
因此,您只需将对象实例化为派生
类型,而不是ABC
请注意,如果操作是静态的,虚拟方法的使用是不可能的,这里不清楚是否是静态的。我正在准备答案,但Gulzar同时回答了(他的答案结束)
你需要的是C++中的一个基本概念/机制,叫做“强>动态绑定< /强>(也许你在你的帖子是1个月的时候同时学习了)< /P>
#包括
#包括
使用名称空间std;
类ABC_基
{
公众:
//纯虚成员函数
//强制有效创建
//子类中的函数
虚拟整数运算(整数,整数)=0;
//将派生虚拟xtor作为基础
虚拟~ABC_Base(){}
};
ABC_M1类:公共ABC_基地
{
int运算(inta,intb){返回a+b;}
};
ABC_M2类:公共ABC_基地
{
int运算(inta,intb){返回a*b;}
};
ABC_Base*创建ABC(字符串xml_文件名)
{
int标准=0;
//nullptr至少需要c++11选项
ABC_Base*ptr=nullptr;
//读取xml文件并更新标准
//请参阅其他帖子
//标准=。。。
开关(标准)
{
案例0:
ptr=新的ABC_M1();
打破
案例1:
ptr=新的ABC_M2();
打破
违约:
打破
}
返回ptr;
}
int main()
{
ABC_Base*ptr=createABC(“My_Config.xml”);
if(nullptr!=ptr)
{
无法操作(3,4)您已经尝试过一些东西了吗?欢迎编写一个小草稿并更具体一些。选择编译时xml文件究竟是什么意思?您希望如何在编译时读取xml文件?这完全取决于您使用的构建系统。例如,使用makefiles,这是可行的。使用Visual Studio IDE,我不知道这是一个简单的方法。因为这不能在C++代码中完成,所以必须在编译器之外完成,就像一个脚本,在编译之前读取XML,并通过将编译宏插入到VS项目文件中来改变编译、FE。但是我想知道是否有任何这样的解决方案有意义的。<代码>如果< /COD>和switch
语句是如何根据某些运行时条件选择要执行的代码分支。您还可以查看vtable和vptr的概念,了解动态绑定在内部的工作方式
class Derived : public ABC{
operate(int op1, int op2){
return op1 * op2; //multiply
}
}
#include <iostream>
#include <cstddef>
using namespace std;
class ABC_Base
{
public:
//pure virtual member function
//compelling effective creation of the
//function in the daughter classes
virtual int operate(int,int) = 0;
//virtual xtor as base will be derived
virtual ~ABC_Base() {}
};
class ABC_M1 : public ABC_Base
{
int operate (int a, int b ) {return a+b; }
};
class ABC_M2 : public ABC_Base
{
int operate (int a, int b ) {return a*b; }
};
ABC_Base * createABC(string xml_filename)
{
int criterion = 0;
// nullptr need at least c++11 option
ABC_Base * ptr = nullptr;
//read xml file and update criterion
//see other post to do that
//criterion = ...
switch(criterion)
{
case 0:
ptr = new ABC_M1();
break;
case 1:
ptr = new ABC_M2();
break;
default:
break;
}
return ptr;
}
int main()
{
ABC_Base * ptr = createABC("My_Config.xml");
if (nullptr != ptr)
{
cout << ptr->operate(3,4) << endl;
}
// If you absolutely want / have to use plain old pointers
// do not forget to release things
// works even if ptr is null, so unconditional delete
delete(ptr);
return 0;
}