我有以下代码:
struct A
{
virtual void foo() {std::cout << "A\n";}
};
struct B : public A
{
virtual void foo() {std::cout << "B\n";}
};
void bar(A * a)
{
a->foo();
}
如果不更改此代码,是否可以将bp
指针转换为B,以便调用bar
将打印"A"?
int main()
{
B * bp = new B();
bar(/* do somethig*/ bp);
return 0;
}
试过我记忆中的每一个演员:
int main()
{
B * bp = new B();
bar((A*)bp);
bar(static_cast<A*>(bp));
bar(reinterpret_cast<A*>(bp));
bar(dynamic_cast<A*>(bp));
return 0;
}
发布于 2022-03-28 02:43:18
您可以围绕B
制作一个shim包装器,并将shim的虚拟函数分派给直接调用A::foo();
的BWrap::foo()
调用。
在这个示例中,携带B&
成员变量引用实际上没有任何意义,但是对于更有趣的示例,可能有一个用例。
struct BWrap : public A
{
B& b;
BWrap(B& bb) : b{bb} {}
virtual void foo() { b.A::foo(); }
};
int main()
{
B* bp = new B();
BWrap bw{*bp};
bar(&bw);
}
发布于 2022-03-28 01:55:51
如果您坚持A
对象是B
对象的一个基类子对象,并且根本不修改第一个代码段,那么唯一的解决方案是添加一个更派生的类,它可以覆盖虚拟调用,正如@Eljay在回答中所解释的那样(我在第一次编写这个答案时完全忘记了这个问题)。
其他选项是创建一个完整的A
对象,而不是B
对象,或者通过使用限定名修改bar
以执行不需要虚拟调度的调用:
a->A::foo();
您显示的所有强制转换都具有与隐式转换相同的效果,但reinterpret_cast
除外,使用这种方式会导致未定义的行为。
https://stackoverflow.com/questions/71641560
复制相似问题