gpt4 book ai didi

c++ - 虚函数和多态

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:07:51 25 4
gpt4 key购买 nike

假设我有这个:

class A
{
public:
virtual int hello(A a);
};

class B : public A
{
public:
int hello(B b){ bla bla };
};

所以,它是一个抽象类。

1) 在 B 类中,我定义了一个方法,它假设重写了 A 类。但参数略有不同。我不确定,这是正确的吗?也许是因为多态性,这没问题,但相当困惑。2) 如果我这样做:A a = new B;,然后 a.hello(lol);如果“lol”不是 B 类型,那么它会给出编译错误?如果它是来自另一个类 C(C 类:public A)的 A 类型,会发生什么?

我对覆盖和虚拟的东西感到困惑。我发现所有示例都使用没有参数的方法。

任何答案、链接或任何值得赞赏的内容。

谢谢

pd:对不起我的英语

最佳答案

您的类 B 不会覆盖 A 中的成员函数,而是重载它。或者尝试无论如何,稍后再看关于隐藏的内容。

重写是指派生类从基类定义自己的虚拟成员函数版本。重载是当您定义具有相同名称的不同函数时。

当对具有基类类型的指针或引用进行虚拟调用时,它只会“考虑”派生类中的覆盖,而不是重载。这是必不可少的 - 对于 B 的实例,调用者将其视为 A 可以做的一切(这是动态多态性和虚函数的要点),它的 hello 函数需要能够接受类型 A 的任何对象。hello 函数只接受类型 B 的对象,而不是任何 A,限制性更强。它不能起到 A 的 hello 函数的作用,所以它不是覆盖。

如果您尝试在 A 和 B 上调用 hello,传递 A 或 B 类型的对象,您应该能够看出区别。 A 有一个接受 A 的函数(你没有定义它,所以如果你调用它那么你的程序将无法链接,但你可以修复它)。 B 有一个接受 B 的函数。它们恰好具有相同的名称,当然,由于 B 派生自 A,您可以将 B 传递给接受 A 的函数。但是 B 的函数在虚拟调用中不充当重写.

可以在 B 对象上调用 A 的函数,但只能通过指向 A 的引用或指针。C++ 的一个特点是 B 中 hello 的定义隐藏了 A 中的定义。如果重载是你想要的,可以通过添加 using A::hello; 到类 B 来取消隐藏基类函数。如果你想要重载,你必须定义一个函数相同的参数。例如:

#include <iostream>

class A
{
public:
virtual int hello(A a) {std::cout << "A\n"; }
virtual int foo(int i) { std::cout << "A::Foo " << i << "\n"; }
};

class B : public A
{
public:
using A::hello;
// here's an overload
int hello(B b){ std::cout << "B\n"; };
// here's an override:
virtual int foo(int i) { std::cout << "B::Foo " << i << "\n"; }
};

int main() {
A a;
B b;
a.hello(a); // calls the function exactly as defined in A
a.hello(b); // B "is an" A, so this is allowed and slices the parameter
b.hello(a); // OK, but only because of `using`
b.hello(b); // calls the function exactly as defined in B
A &ab = b; // a reference to a B object, but as an A
ab.hello(a); // calls the function in A
ab.hello(b); // *also* calls the function in A, proving B has not overridden it
a.foo(1); // calls the function in A
b.foo(2); // calls the function in B
ab.foo(3); // calls the function in B, because it is overridden
}

输出:

A
A
A
B
A
A
A::Foo 1
B::Foo 2
B::Foo 3

如果您从 B 中删除 using A::hello; 行,则调用 b.hello(a); 将无法编译:

error: no matching function for call to `B::hello(A&)'
note: candidates are: int B::hello(B)

关于c++ - 虚函数和多态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2440285/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com