为什么dynamic_cast(this)在构造函数中不起作用以及如何使其工作?

Bha*_*rag 0 c++

我使用CRTP移动的共同实施D1,并D2为模板,然而,构建对象时,我必须做出调用具体到每种类型的重载函数.

以下代码的输出是

D 0x7ffc7d370538
D1 0
D 0x7ffc7d370540
D2 0
Run Code Online (Sandbox Code Playgroud)

虽然预期产量是

D 0x7ffc7d370538
D1 0x7ffc7d370538
D 0x7ffc7d370540
D2 0x7ffc7d370540
Run Code Online (Sandbox Code Playgroud)

为什么dynamic_cast返回nullptr?如何修复此代码?

#include <iostream>

template <typename Derived>
struct B {
    B();
    virtual ~B() {}
};

struct D1 : B<D1> {
};

struct D2 : B<D2> {
};

void use(D1* d) { std::cout << "D1 " << d << std::endl; }
void use(D2* d) { std::cout << "D2 " << d << std::endl; }

template <typename Derived>
B<Derived>::B() {
    std::cout << "D " << this << std::endl;
    Derived* derivedThis = dynamic_cast<Derived*>(this);
    use(derivedThis);
}

int main() {
    D1 d1;
    D2 d2;
}
Run Code Online (Sandbox Code Playgroud)

我找到的唯一解决方法如下

#include <iostream>

template <typename Derived>
struct B {
    B();
    virtual ~B() {}
};

struct D1;
struct D2;

void use(D1* d) { std::cout << "D1 " << d << std::endl; }
void use(D2* d) { std::cout << "D2 " << d << std::endl; }

struct D1 : B<D1> {
    D1() { use(this); } # code duplication
};

struct D2 : B<D2> {
    D2() { use(this); } # code duplication
};

template <typename Derived>
B<Derived>::B() {
    std::cout << "D " << this << std::endl;
}

int main() {
    D1 d1;
    D2 d2;
}
Run Code Online (Sandbox Code Playgroud)

但是在我的场景中,重复调用函数的代码重复太多了use.例如,可以有许多派生类,或许多类似于函数的调用use.

Ser*_*eyA 5

麻烦的直接原因是在构造派生类之前调用​​基类构造函数.因此,dynamic_class在构造函数中进行转换会导致nullptr.

没有办法绕过它,你不能从基类构造函数中使用派生类的对象.

另一方面,当在同一个类中使用运行时和编译时多态时,通常它是一种设计气味.坚持他们中的任何一个.