【问题标题】:How can I pass base class pointer in a CRTP implementation如何在 CRTP 实现中传递基类指针
【发布时间】:2018-07-26 09:17:35
【问题描述】:

我正在将具有纯虚拟方法的普通继承的代码转换为 CRTP,以避免虚拟方法的开销 (see here)。

在我删除 CRTP 实现中调用方法的注释之前,转换工作得非常好(它给出了compilation error: use of undeclared identifier 'T')我如何在 CRTP 中实现相同的调用方法,这在普通继承中没有问题?换句话说,是否可以像普通继承一样传递指向基类的指针?

当然,我可以通过在类模板中移动调用方法来解决问题,但是对于我的用例,它不属于那里(我这里没有给出我的实际代码,这很长)。有什么想法吗?

转换前的代码如下:

#include <iostream>

class Base
{
public:
    void interface() {
        implementation();
    }
    virtual void implementation() = 0;
};

class Derived1 : public Base
{
public:
    void implementation() {
        std::cout << "Hello world 1" << std::endl;
    }
};

class Derived2 : public Base
{
public:
    void implementation() {
        std::cout << "Hello world 2" << std::endl;
    }
};

void call(Base *b) {
    b->interface();
    // ... do other things ...
}

int main() {
   Derived1 d1;
   Derived2 d2;
   call(&d1);
   call(&d2);
}

转换后的代码 (CRTP) 如下所示:

#include <iostream>

template <class T> 
class Base
{
public:
    void interface() {
        static_cast<T*>(this)->implementation();
    }
};

class Derived1 : public Base<Derived1>
{
public:
    void implementation() {
        std::cout << "Hello world 1" << std::endl;
    }
};

class Derived2 : public Base<Derived2>
{
public:
    void implementation() {
        std::cout << "Hello world 2" << std::endl;
    }
};

//void call(Base<T> *b) {
//    b->interface();
//    // ... do other things ...
//}

int main() {
   Derived1 d1;
   Derived2 d2;
   //call(&d1);
   //call(&d2);
   d1.interface();
   d2.interface();
}

【问题讨论】:

  • call 方法显然也需要是一个模板。
  • 没有通用的基类了。 Base&lt;Derived1&gt;Base&lt;Derived2&gt; 是不同的、不相关的类型。通过转换为 CRTP,您基本上将运行时多态性转换为编译时多态性。如果您想要运行时多态性,请使用虚拟方法,这就是它们的用途……
  • @arunatsiara.cc 正确,但这正是使 call 成为模板的目的。

标签: c++ crtp


【解决方案1】:

你错过了一些语法。正确声明:

template<class T> // <--- this was missing
void call(Base<T> *b) {
    b->interface();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    • 2018-07-12
    相关资源
    最近更新 更多