我使用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.
麻烦的直接原因是在构造派生类之前调用基类构造函数.因此,dynamic_class在构造函数中进行转换会导致nullptr.
没有办法绕过它,你不能从基类构造函数中使用派生类的对象.
另一方面,当在同一个类中使用运行时和编译时多态时,通常它是一种设计气味.坚持他们中的任何一个.
| 归档时间: |
|
| 查看次数: |
61 次 |
| 最近记录: |