在不指向对象的情况下调用虚方法?
calling virtual method without pointing to an object?
#include <iostream>
struct A {
void init()
{
internal_init();
}
virtual void internal_init()
{
std::cout << "internal of A" << std::endl;
}
};
struct B: public A {
void internal_init()
{
init();
std::cout << "internal of B" << std::endl;
}
};
int main(){
B instance;
std::cout << "internal of A" << std::endl;
instance.internal_init();
return 0;
}
首先,程序按预期进入 B::internal_init()
。
然后,到 A::init()
(我想因为 B 派生自 A ,而 B 没有任何 init()
)。
现在怎么办?
它会选择什么internal_init()
?因为到了B::internal_init()
,程序会进入死循环,我不明白为什么。
- 当我调用
internal_init()
时到底发生了什么?
- 为什么调用实例"B part"的
internal_init()
?这是关于 "virtual" 的吗?如果是这样,怎么会?虚函数发生在我们使用多态性时(据我这样的初学者理解,它使用基 class 的 指针 指向派生 class 个对象)。
因为 instance
是 B
instance.internal_init();
将调用 B
s internal_init()
。然后在 internal_init()
中调用 init();
。现在成员函数有一个隐式参数,即 this 指针。
所以当我们调用A
的init()
时,这个指针实际上是一个B
。在 init()
中,我们使用指向 B
的 this 指针调用 internal_init();
。由于 internal_init()
是虚拟的并且我们有一个指向 B
的指针,因此虚拟查找机制将调用 B
的 internal_init()
.
这将再次循环并最终导致段错误或堆栈溢出。
首先struct B
因为struct B: public A
继承了struct A
的所有功能。 A
的函数 internal_init
在 B
中被覆盖,因为您在 A
.
中使用相同的函数签名和关键字 virtual
所以现在调用是:
instance.internal_init();
调用 B
的 internal_init()
,调用 A::init
,调用 B::internal_init()
,等等,直到给出分段错误。
为了防止这种情况(我认为这就是你想要的),你可以在 B
中显式调用 A
的 internal_init()
而不是调用 init()
:
struct B: public A {
virtual void internal_init()
{
A::internal_init();
std::cout << "internal of B" << std::endl;
}
};
#include <iostream>
struct A {
void init()
{
internal_init();
}
virtual void internal_init()
{
std::cout << "internal of A" << std::endl;
}
};
struct B: public A {
void internal_init()
{
init();
std::cout << "internal of B" << std::endl;
}
};
int main(){
B instance;
std::cout << "internal of A" << std::endl;
instance.internal_init();
return 0;
}
首先,程序按预期进入 B::internal_init()
。
然后,到 A::init()
(我想因为 B 派生自 A ,而 B 没有任何 init()
)。
现在怎么办?
它会选择什么internal_init()
?因为到了B::internal_init()
,程序会进入死循环,我不明白为什么。
- 当我调用
internal_init()
时到底发生了什么? - 为什么调用实例"B part"的
internal_init()
?这是关于 "virtual" 的吗?如果是这样,怎么会?虚函数发生在我们使用多态性时(据我这样的初学者理解,它使用基 class 的 指针 指向派生 class 个对象)。
因为 instance
是 B
instance.internal_init();
将调用 B
s internal_init()
。然后在 internal_init()
中调用 init();
。现在成员函数有一个隐式参数,即 this 指针。
所以当我们调用A
的init()
时,这个指针实际上是一个B
。在 init()
中,我们使用指向 B
的 this 指针调用 internal_init();
。由于 internal_init()
是虚拟的并且我们有一个指向 B
的指针,因此虚拟查找机制将调用 B
的 internal_init()
.
这将再次循环并最终导致段错误或堆栈溢出。
首先struct B
因为struct B: public A
继承了struct A
的所有功能。 A
的函数 internal_init
在 B
中被覆盖,因为您在 A
.
virtual
所以现在调用是:
instance.internal_init();
调用 B
的 internal_init()
,调用 A::init
,调用 B::internal_init()
,等等,直到给出分段错误。
为了防止这种情况(我认为这就是你想要的),你可以在 B
中显式调用 A
的 internal_init()
而不是调用 init()
:
struct B: public A {
virtual void internal_init()
{
A::internal_init();
std::cout << "internal of B" << std::endl;
}
};