我有一个C ++类,其中有两个私有方法的重载,而这些应该与一个公共方法的两个重载连接。
两个重载中的public方法都是相同的,仅在调用的私有方法的重载方面有所不同。另一方面,这两个私有方法重载完全不同,这就是为什么我选择首先重载它们的原因。
为避免在public方法中重复代码,这似乎是完美转发的一个好用例。但是,另一方面,如果您想调用公共方法并且不熟悉API,则很难看到必须提供哪些参数。您将必须检查公共方法的主体,然后查阅私有接口以查看私有方法的哪些重载。
我试图做一个玩具班来说明我的问题:
class Foo {
public:
struct DontCopyTheBaz {};
private:
bool init_from_baz(Baz& a_baz);
bool init_from_baz(Baz& a_baz, DontCopyTheBaz);
public:
// ...should I use perfect forwarding, making the API not easily readable?
template<typename... Args>
static Foo* new_for_baz(Baz& a_baz, Args&&... args) {
Foo* the_foo = new Foo();
if (!the_foo->init_from_baz(a_baz, std::forward<Args>(args)...)) {
delete the_foo;
return nullptr;
}
return the_foo;
}
// ...or should I write duplicated code?
static Foo* new_for_baz(Baz& a_baz) {
Foo* the_foo = new Foo();
if (!the_foo->init_from_baz(a_baz)) {
delete the_foo;
return nullptr;
}
return the_foo;
}
static Foo* new_for_baz(Baz& a_baz, DontCopyTheBaz no_copy) {
Foo* the_foo = new Foo();
if (!the_foo->init_from_baz(a_baz, no_copy)) {
delete the_foo;
return nullptr;
}
return the_foo;
}
};
(实际上,私有方法和公共方法都更长且更复杂。)
有没有一种方法可以避免代码重复,同时又使API易于理解?
答案 0 :(得分:2)
您可以添加额外的间接方式来分解代码并使界面整洁:
class Foo {
public:
struct DontCopyTheBaz {};
private:
bool init_from_baz(Baz& a_baz);
bool init_from_baz(Baz& a_baz, DontCopyTheBaz);
template<typename... Args>
static std::unique_ptr<Foo> new_for_baz_impl(Baz& a_baz, Args&&... args) {
auto the_foo = std::make_unique<Foo>();
if (!the_foo->init_from_baz(a_baz, std::forward<Args>(args)...)) {
return nullptr;
}
return the_foo;
}
public:
static std::unique_ptr<Foo> new_for_baz(Baz& a_baz) {
return new_for_baz_impl(a_baz);
}
static std::unique_ptr<Foo> new_for_baz(Baz& a_baz, DontCopyTheBaz no_copy) {
return new_for_baz_impl(a_baz, no_copy);
}
};