如何轻松地覆盖多个重载方法
How to easily override multiple overloaded methods?
假设我有一个接口和一个实现它的类,像这样:
class IPrinter
{
public:
virtual void print(int i, int base = 10) = 0;
virtual void print(char c) = 0;
virtual void print(char *s) = 0;
virtual void print(float f) = 0;
virtual void print(double d) = 0;
virtual ~IPrinter() = default;
private:
...
}
class Printer : public IPrinter
{
public:
void print(int i, int base = 10) override {...}
void print(char c) override {...}
void print(char *s) override {...}
void print(float f) override {...}
void print(double d) override {...}
private:
...
}
然后我决定添加一个简单的装饰类,像这样:
class SwitchablePrinter : public IPrinter
{
private:
IPrinter& _printer;
bool _enabled;
...
public:
SwitchablePrinter(IPrinter& p) :
_printer(p),
_enabled(true)
{
}
void print_enable(bool on) { _enabled = on; }
void print(int i, int base = 10) override
{
if (_enabled)
_printer.print(i, base);
}
void print(char c) override
{
if (_enabled)
_printer.print(c);
}
void print(char *s) override
{
if (_enabled)
_printer.print(s);
}
void print(float f) override
{
if (_enabled)
_printer.print(f);
}
void print(double d) override
{
if (_enabled)
_printer.print(d);
}
}
现在,所有这些都非常简单和直接。问题是SwitchablePrinter实现中有很多重复的代码。我想知道,如果有一种方法可以为基类中的所有重载方法写一个泛型方法"打印",就像这样:
(pseudo-code)
void print({any args})
{
if (_enabled)
_printer.print({any args});
}
我认为使用模板可能有一个解决方案,但我对使用它们不是很有经验,需要建议。
虽然没有机制可以一次覆盖多个成员函数,但是您可以通过提供一个私有可变成员函数模板来简化您的任务并减少代码重复,该模板将调用转发给包装的_printer
的适当重载,如:
private:
template <class ... T>
void print_impl(T ... vals) {
if (_enabled)
_printer.print(vals...);
else
cout << "disabled" << endl;
}
public:
void print(int i, int r) override {
print_impl(i, r);
}
void print(float f) override {
print_impl(f);
}
void print(double d) override {
print_impl(d);
}
void print(char* s) override {
print_impl(s);
}
void print(char c) override {
print_impl(c);
}
演示。
由于print_impl
的转发逻辑非常简单,所以这只是在原来的基础上的一个小小的改进。当逻辑变得更复杂时,共享代码的收益就会增加。
显然要尝试用
替换SwitchablePrinter中的实现。template<typename T>
void print(T t) override
{
if (_enabled)
_printer.print(t);
}
(忽略整数打印方法存在问题)
但是这不起作用,因为成员函数模板不能是虚的:c++类成员函数模板可以是虚的吗?(请参阅点赞最多的答案,而不是公认的答案。)所以你目前的SwitchablePrinter实现是最好的,就我所见。
相关文章:
- 重载方法的方式会在使用临时调用时生成编译器错误
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 一种优雅或至少可行的方法,用于使用和接受具有重载方法和运算符的不同大小的文字数组常量
- 使用 nullptr 调用重载方法是不明确的
- 具有重载方法的可变参数数据结构
- C++11 重载方法,并转发到唯一方法
- 获取特定的模板重载方法指针
- std::result_of 应用于 const 重载方法
- 重载方法的类接受模板和基类 - 如何默认某个方法
- 推导模板类重载方法的地址会导致"error: expected primary-expression before ‘decltype’"
- C++如何使用按值传递和按引用传递的重载方法
- 具有原始方法参数派生类的 C++ 重载方法参数
- SWIG:在派生类中处理基类重载方法
- 在c++中的赋值运算符重载方法中删除旧的动态分配内存
- C++选择'wrong'默认参数的重载方法
- 重写重载方法会隐藏一些重载
- 在C++中,如何从父类变量的子类调用重载方法
- 所有重载方法的别名
- 使用 SWIG 在重载C++方法中设置类型