c++ - 虚函数和多态

标签 c++ polymorphism virtual

假设我有这个:

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/

相关文章:

c++ - Std 或 boost atomic unsigned char[32]

c++ - 无法检测到 USB 设备

c# - 接口(interface)是否兼容多态性

c++ - 指针向下转换和向上转换的用法区别?

c++ - 删除 C++ 中的重复模式

Java虚拟游戏 handle

c++ - 如何执行程序执行检查

c++ - 进程 "mingw32-make.exe"崩溃错误

java - 从 Java 调用多态 Scala 方法

c++ - 请告诉我为什么虚函数在以下代码中不起作用