【问题标题】:Derived to base implicit pointer type conversion派生到基础隐式指针类型转换
【发布时间】:2017-06-29 09:58:34
【问题描述】:

对于一个通用的树形结构,我正在使用一些看起来像这样的代码(以下代码是一个 MCVE):

template <typename T> class Base {
protected:
  Base() {}

public:
  T *ptr;
  void setRelated() { ptr = this; }
};

class Derived : public Base<Derived> {};

int main() {
  Derived d;
  d.setRelated();
  return 0;
}

基本原理:这样做的原因是为了让使用此类的开发人员不必为此类中使用的每个调用和算法将所有内容从基类转换为派生类再返回,尤其是基础是抽象的,不能自己实例化。

此代码无法编译。它说:

main.cpp:7: error: invalid conversion from ‘Base<Derived>*’ to ‘Derived*’ [-fpermissive]
   void setRelated() { ptr = this; }
                   ~~~~^~~~~~

问题:有没有办法使从Base&lt;Derived&gt;*Derived* 的所有转换都隐式(假设我们不应该重载每个方法)?

【问题讨论】:

    标签: c++ class c++11 templates polymorphism


    【解决方案1】:

    ...尤其是基础是抽象的,不能自己实例化。

    您不能直接将Base 抽象化。这需要从另一个派生 指定纯虚函数的类(接口)1.


    有没有办法让所有从 Base* 到 Derived* 的转换都是隐式的(假设我们不应该重载每个方法)?

    不,没有。

    CRTP 的典型用法是使用static_cast

     void setRelated() { ptr = static_cast<T*>(this); }
    

    1 看看STTCL,我在其中广泛使用了该技术。

    【讨论】:

    • 感谢您的回答。如果setRelated 有指针作为参数怎么办?我发现自己必须提供 2 个重载(一个用于 Base&lt;Derived&gt;*,另一个用于 Derived*。这是唯一的方法吗?
    • @TheQuantumPhysicist AFAIK 这是处理它的唯一方法。问题是又名 静态多态性
    • 我明白了...谢谢。
    • 致您的编辑:我并不是说具有纯虚函数是抽象的。我的意思是抽象的,只是在没有继承的情况下使其不可实例化。效果是一样的,只是没有方法需要重载。
    • @TheQuantumPhysicist 你的意思是protected 构造函数?是的,这对于实例化具有相同的效果,但不会使基类 abstract 就该术语的常见用法而言。 ATM 如果没有提供有关您的实际用例的更多背景信息,我无法判断您是否正在解决 XY 问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多