【问题标题】:Static polymorphism and method names c++静态多态性和方法名称 c++
【发布时间】:2012-12-01 09:00:39
【问题描述】:

当我使用静态多态 (CRTP) 时,是否有一种很好的方法可以为多态方法命名?

template <class Derived> 
struct Base
{
    void interface()
    {
        // ...
        static_cast<Derived*>(this)->implementation();
        // ...
    }

    static void static_func()
    {
        // ...
        Derived::static_sub_func();
        // ...
    }
};

struct Derived : Base<Derived>
{
    void implementation();
    static void static_sub_func();
};

因为,据我所知,接口和实现不能有相同的名称(如果它们是虚拟的,它们就会有相同的名称)。如果类层次结构很深,那就有点尴尬了。

也许有一些很好的方法来处理它?还是我错了?

【问题讨论】:

  • 为什么接口(实际上是基类)和实现(实际上是派生类)不能同名?
  • 我想virtual 关键字是干什么用的。
  • @georgesl 进行 CRTP 时,您这样做是为了避免 virtual 函数。
  • 接口和实现可以同名。它们不需要是虚拟的,因为它是在编译时解决的。派生类中的 implementation() 将隐藏“base”中的实现。对 Derived 的静态强制转换会导致调用该函数的 Derived 版本。
  • @Pete:虽然他们可以有相同的名字,但这不是一个好主意。意图是derived.interface() 调用基础版本,而后者又调用派生版本;如果它们具有相同的名称,那么将直接调用派生版本。

标签: c++ static-polymorphism


【解决方案1】:

我的方法是避免继承(不管 CRTP 感觉多么可爱),而是使用聚合。类模板提供接口,并反过来提供具有实现的委托类。它看起来像这样:

template <class Delegate>
struct Interface
{
    void do_something()
    {
        // ...
        delegate.do_something();
        // ...
    }

    Delegate delegate;
};

这样做的缺点是向委托对象提供构造函数参数比较麻烦,但这并不难管理。

【讨论】:

  • 这有什么好处?
  • 1.它允许您在接口和实现中为函数赋予相同的名称(根据您的要求)。 2.类关系更简单。 3. 代码更干净,无需强制转换。 4.它不会将实现与接口耦合,因此您定义的任何委托类都可以独立于接口类使用。
【解决方案2】:

当父类没有任何特殊功能时(如在典型的抽象接口中),我看不出您不能在子类中重用函数名的原因。它会隐藏父方法,但这并不重要,因为您静态地告诉编译器您希望使用哪个版本。

但是在您的情况下,似乎您希望父级在调用虚拟方法之前和之后做一些工作(闻起来像模板方法模式)。在这种情况下,无论您使用运行时(虚拟)还是编译时 (CRTP) 多态性,都需要使用备用名称来调用接口和实现方法。

如果 foo 是基类中的接口/模板方法,那么无论运行时或编译时多态如何,do_foo 或 foo_impl 似乎都是实现函数的完全合理的名称。

【讨论】:

    猜你喜欢
    • 2011-10-15
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 2012-01-10
    • 1970-01-01
    • 2014-02-18
    相关资源
    最近更新 更多