我有以下课程。
class A
{
public:
void fun();
}
class B: public A
{
}
class C: public A
{
}
A * ptr = new C;
可以做下面这样的事吗?如果在基类中引入一些虚函数,我会遇到一些问题吗?
((B *)ptr)->fun();
这可能看起来很愚蠢,但我有一个通过B调用A函数的函数,我不想改变它。
答案 0 :(得分:7)
你不能将A *指向C类作为B *,因为C类与B类没有任何关系。你会得到未定义的行为,这可能是被调用的错误函数和堆栈损坏。
如果你打算从C级派生出来,那么你可以。但是,你不需要。如果C类没有定义fun(),它将继承A。你没有声明fun()虚拟,所以如果你甚至实现C :: fun()或B :: fun(),你会得到奇怪的行为。你几乎肯定希望fun()被声明为虚拟。
答案 1 :(得分:0)
你不必进行施法(B *)ptr-> fun();因为fun()已经在基类中。 B类或C类的两个对象都将在您的示例中调用相同的fun()函数。
我不确定当你覆盖B类的fun()函数时会发生什么......
但是在我看来,尝试从另一个类(不是基类)调用函数是不好的OO。
答案 2 :(得分:0)
我在这里猜测,但我怀疑这可能取决于您使用的编译器以及它如何组织vf指针表。
我还要注意,我认为你所做的是一个坏主意,可能导致各种噩梦般的问题(使用像static_cast和dynamic_cast这样的东西通常是一个好主意)。另一件事是因为fun()在基类中定义(并且它不是虚拟的)ptr-> fun()将始终调用A :: fun()而不必将其强制转换为B *。
答案 3 :(得分:0)
你可以从A *转换为B *,如果原始指针是B *,它应该可以工作。
A* p = new B;
B* q = static_cast<B*>(p); // Just work (tm)
但是在这种情况下它是一个C *,它不能保证工作,你会以一个悬空指针结束,如果你很幸运你将获得访问冲突,如果不是你,你最终会默默地腐蚀你的记忆。
A* p = new C;
B* q = static_cast<B*>(p); // Owned (tm)