C++ 使用继承时避免重复相同的代码

C++ 使用继承时避免重复相同的代码,c++,C++,假设我有这门课 struct IDebug { virtual void print(std::ostream&) const = 0; }; 并且打印应该遵循为实现IDebug的每个类定义的格式 该格式是静态的,因为对于特定的实现,将始终具有相同的格式,并且我希望使用该格式,而不管我是否有该类的任何实例(例如在程序初始化时) 因此,我添加了一个: static std::string format(); 到每个实现类。丑陋(因为它不是由界面强制的),但我可以接受 现在我想

假设我有这门课

struct IDebug {
    virtual void print(std::ostream&) const = 0;
};
并且打印应该遵循为实现
IDebug
的每个类定义的格式

该格式是静态的,因为对于特定的实现,将始终具有相同的格式,并且我希望使用该格式,而不管我是否有该类的任何实例(例如在程序初始化时)

因此,我添加了一个:

static std::string format(); 
到每个实现类。丑陋(因为它不是由界面强制的),但我可以接受

现在我想在接口级别添加一些验证,实际的
print()
遵循这个类定义的格式。为此,我必须进行修改:

struct IDebug {
   void print(std::ostream& o) const { // no longer virtual
     auto format = format_impl();
     // preprocess using format
     print_impl(o);
     // postprocess using format
   }

protected:
   virtual void print_impl(std::ostream& o) const = 0;
   virtual std::string format_impl() const = 0;
};
每个实现类现在都有完全相同的代码行:

std::string format_impl()const override{return format();}

struct MooDebug : public IDebug { 
    // rest of the code
    static std::string format() { return "whatever"; } // this was already here. sadly the interface couldn't force it
    std::string format_impl() const override { return format(); } // all implementing classes are repeating this exact line
};

我正在寻找如何避免或改进它的建议。

您可以使用一些类似CRTP的类来创建一个实现所需功能的基类:

struct MooDebug : DebugHelper<MooDebug>
{
static std::string format() { return "whatever"; }
};

 template<typename T>
struct DebugHelper : IDebug
 {
     std::string format_impl() const override { return T::format(); }
  };

根据@JVApen的回答,我最终做了以下工作:

template <class T>
struct IDebug {
   void print(std::ostream& o) const { // no longer virtual
     auto myformat = T::format();
     // preprocess using format
     print_impl(o);
     // postprocess using format
   }

protected:
   virtual void print_impl(std::ostream& o) const = 0;
};
模板
结构IDebug{
无效打印(std::ostream&o)常量{//不再是虚拟的
自动myformat=T::format();
//使用格式进行预处理
打印impl(o);
//使用格式进行后处理
}
受保护的:
虚空打印(std::ostream&o)常量=0;
};

现在我们还强制(直到没有正确使用CRTP)format()的静态实现,这是一个很好的额外好处

为什么要使
format\u impl
纯虚拟?如果它要做的只是调用
format()
函数,为什么还要麻烦
format\u impl
呢?为什么不直接调用
format()
?或者,如果您以后可能要为不同的格式覆盖它,那么不要将其设置为纯虚拟,并在
IDebug
类中实现它。这听起来像是要使用模板方法设计模式:@Someprogrammerdude,因为它不能调用实现静态方法?@CinCout否则您将如何实现它?这很好。我仍然不确定IDebug将如何使用格式impl来运行它应该运行的验证
template <class T>
struct IDebug {
   void print(std::ostream& o) const { // no longer virtual
     auto myformat = T::format();
     // preprocess using format
     print_impl(o);
     // postprocess using format
   }

protected:
   virtual void print_impl(std::ostream& o) const = 0;
};