C++ 如果两个不相关的类型共享一个公共(可能未知)子类,是否可以在它们之间进行动态_强制转换?
抱歉,如果问题标题没有意义,但我不确定如何简洁地描述我试图解决的问题。问题是: 我正在使用一个C++库,它大量使用了一个类,我们称之为“代码> BASE< /COD> ”。C++ 如果两个不相关的类型共享一个公共(可能未知)子类,是否可以在它们之间进行动态_强制转换?,c++,templates,polymorphism,dynamic-cast,static-cast,C++,Templates,Polymorphism,Dynamic Cast,Static Cast,抱歉,如果问题标题没有意义,但我不确定如何简洁地描述我试图解决的问题。问题是: 我正在使用一个C++库,它大量使用了一个类,我们称之为“代码> BASE< /COD> ”。 此库有几个不同的子类继承自Base。我们将这些类称为Child1,Child2。。等等 此库允许用户创建自己的Base子类,并让库使用这些类的实例。我现在有这样的东西: 然后我使用的库将具有如下功能: void foo(Base* base); // code... Base *base = getSomeBase();
Base
。我们将这些类称为Child1
,Child2
。。等等Base
子类,并让库使用这些类的实例。我现在有这样的东西:void foo(Base* base);
// code...
Base *base = getSomeBase(); // getSomeBase() is a function from the library that returns a Base*
Custom* myCustom = static_cast<Custom*>(base); // I always make the library use my `Custom` class, so this is safe.
myCustom->doSomething();
template <class Child_t>
class Custom : public Child_t // inherit from Child_t, which inherits from Base
{
public:
// override virtual functions here
// ...
void doSomething(); // Utility function I created
}
我可以传入一个指向我的自定义类的指针。没问题,一切都很好。有时,我可能需要从库中接收指向Base
对象的指针,并对其进行处理。看起来是这样的:
void foo(Base* base);
// code...
Base *base = getSomeBase(); // getSomeBase() is a function from the library that returns a Base*
Custom* myCustom = static_cast<Custom*>(base); // I always make the library use my `Custom` class, so this is safe.
myCustom->doSomething();
template <class Child_t>
class Custom : public Child_t // inherit from Child_t, which inherits from Base
{
public:
// override virtual functions here
// ...
void doSomething(); // Utility function I created
}
让库使用新模板化的Custom
类没有问题,因为只要模板参数Child\u t
实际上是从Base
继承的库的子类之一,我的Custom
类就可以简单地转换为Base*
。当试图朝另一个方向前进时,会出现问题:
Base *base = getSomeBase();
/* ?????
Would like to call base->doSomething();
But I have no idea which Custom class I have received here. "base" could be
a Child1*, Child2*, etc. There's no way for me to perform a cast.
*/
我被卡住了。请注意,我的函数doSomething()。我最初的想法是将我的doSomething()
函数移动到一个接口类中
class Interface
{
public:
virtual void doSomething() = 0;
}
然后让每个自定义类实现如下接口:
template <class Child_t>
class Custom : public Child_t, public Interface
{
void doSomething() override;
}
这是一个丑陋的解决方案。这也给开发人员带来了额外的认知负担,因为如果他们在任何时候决定需要使用自定义
、自定义
、自定义
等类,他们必须记住返回并更新if-else链,以彻底检查每个可能的情况。所以我的问题是:
是否有可能在编译时调用Base*
对象上的doSomething()
函数,而不实际知道我拥有哪个自定义
类,也不简单地尝试所有可能的动态转换
?因此,我的问题的标题是:如果我知道它们共享一个公共子类(我只是不知道是哪个子类),我是否可以以某种方式将Base*
转换为接口*
我是不是完全错了
您应该使用dynamic\u cast(base)
结构B{virtual~B(){};
结构I{virtual int foo()=0;};
结构X:B{};
结构Y:I,X{virtualintfoo(){return 10;}};
结构Z:I,X{virtualintfoo(){return 20;}};
int main(){
B*x=新的Z;
I*I=动态投影(x);
返回i->foo();
}
< P> >动态> CAST(BASE)< /代码>……或者如果只有一个可能的<代码>接口< /代码>,我会考虑把各种<代码>虚空隙量()= 0的机会;<直接在
Base
中执行code>,避免多重继承和动态强制转换。最初的方法是将Base
向下转换为Custom
,以调用专门的方法,这听起来很可疑,我将回顾导致that@MatG是的,理想情况下,接口应位于基座上。但是Base
是一个来自我链接的库的类,我没有完整的源代码(只有.h文件和.lib文件)。因此,我无法修改Base
以包含doSomething()
函数。非常感谢!出于某种原因,我只是假设dynamic_cast无法执行这种类型的转换。我想我的印象是,动态和静态演员在你可以在哪种类型之间进行演员转换上有着完全相同的限制。现在我知道了!我应该从一开始就尝试使用dynamic_cast。@ChristianDaley没问题:)你也提供了很好的问题和细节:)