下面的代码可以正常编译和运行。但是,对我来说,函数workflow1
和workflow2
中有重复的代码,事实上,唯一的区别是workflow2
中增加了参数y
,以及对method1
/method2
的不同调用。有没有办法用一个函数来代替这两个函数?也许有一种方法可以将函数(workflow1
或workflow2
)及其参数作为参数传递给另一个通用函数(例如workflow
)?也许这类工作存在一些设计模式?
class MyClass
{
public:
void workflow1(int x) {
doThings(); // actually some code more than just one function call
method1(x);
doOtherThings(); // actually some code more than jus one function call
}
void workflow2(int x, int y=1) {
doThings(); // actually some code; the same as in workflow1()
method2(x,y);
doOtherThings(); // actually some code; the same as in workflow1()
}
private:
void doThings() {}
void doOtherThings() {}
void method1(int x) {}
void method2(int x, int y) {}
};
int main()
{
MyClass myClass;
int x = 0;
myClass.workflow1(x);
int y = 2;
myClass.workflow2(x, y);
}
两个选项:
使用lambda方法:
#include <functional>
class MyClass
{
public:
void workflow1(int x) {
workFlowInternal([x, this] {method1(x); });
}
void workflow2(int x, int y = 1) {
workFlowInternal([x, y, this] {method2(x,y); });
}
private:
void workFlowInternal(const std::function<void()> &func) {
doThings();
func();
doOtherThings();
}
void doThings() {}
void doOtherThings() {}
void method1(int x) {}
void method2(int x, int y) {}
};
或者使用指向成员函数的指针:
class MyClass
{
public:
void workflow1(int x) {
workFlowInternal(&MyClass::method1, x, 0);
}
void workflow2(int x, int y = 1) {
workFlowInternal(&MyClass::method2, x, y);
}
private:
void workFlowInternal(void(MyClass::* func)(int, int), int x, int y) {
doThings();
(this->*func)(x,y);
doOtherThings();
}
void doThings() {}
void doOtherThings() {}
void method1(int x, int ignored=0) {}
void method2(int x, int y) {}
};
你可以直接使用std::optional
:
#include <optional>
class MyClass
{
public:
void workflow(int x, std::optional<int> y = {}) {
doThings();
if (!y) method1(x);
else method2(x, *y);
doOtherThings();
}
private:
void doThings() { }
void doOtherThings() { }
void method1(int x) { }
void method2(int x, int y) { }
};
int main() {
MyClass myClass;
int x = 0;
myClass.workflow(x);
int y = 2;
myClass.workflow(x, y);
}
演示。
你可以这样写一个模板化的函数:
template <bool workflow1>
void Workflow(int x, int y=1)
{
doThings();
if constexpr (workflow1)
{
method1(x);
}
else
{
method2(x, y);
}
doOtherThings();
}
int main()
{
int x = 0;
Workflow<true>(x);
int y = 2;
Workflow<false>(x, y);
}
if constexpr
语句是在编译时决定的,因此这将生成两个不同的函数,但您不必重写相同的代码。如果需要支持两种以上的类型,可以将模板参数从bool
更改为enum
或其他类型。