虚函数和多态 [英] Virtual functions and polymorphism

查看:167
本文介绍了虚函数和多态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这个:

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

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

所以,它是一个抽象类。

So, A it's an abstract class.

1)在类B中,我定义一个方法,它假设覆盖A类。但参数略有不同。我不知道这个,这是正确的吗?也许是因为多态性,这是确定,但它相当混乱。
2)如果我这样做:A a = new B;然后a.hello(lol);如果lol不是类型B,那么它会给出编译错误?,如果它是类型A从另一个类C(类C:公共A),会发生什么?

1)In the class B, I'm defining a method that its suppose overrides the A class. But the parameter it's slightly different. I'm not sure about this, is this correct? Maybe because of polymorphism, this is ok but its rather confusing. 2) If I do: A a = new B;, and then a.hello(lol); if "lol" it's not of type B, then it would give compile error?, and if it's of type A from another class C (class C : public A), what would happend?

我对于重写和虚拟的东西感到困惑..所有的例子我发现使用没有参数的方法。

I'm confused about the overriding and virtual thing.. all examples I found work with methods without parameters.

任何回答,链接,赞赏。

Any answer, link, or whatever it's appreciated.

感谢

pd:对不起我的英语

pd: sorry for my english

推荐答案

您的类B不会覆盖 A中的成员函数,它会重载

覆盖是指派生类从基类中定义自己的virtual成员函数的版本。重载是在定义具有相同名称的不同函数时。

Overriding is when a derived class defines its own version of a virtual member function from a base class. Overloading is when you define different functions with the same name.

当对具有基类类型的指针或引用进行虚拟调用时,它只会考虑派生类中的覆盖,而不是重载。这是必要的 - 对于B的实例被呼叫者视为一个A可以做的一切(这是动态多态性和虚拟函数的点),它的 hello 函数需要能够获取任何类型的对象A.一个 hello 函数,只接受类型B的对象,而不是任何A,更限制。它不能扮演A的 hello 函数的角色,因此它不是覆盖。

When a virtual call is made on a pointer or reference that has the type of the base class, it will only "consider" overrides in the derived class, not overloads. This is essential - for an instance of B to be treated by callers as though it does everything an A can do (which is the point of dynamic polymorphism and virtual functions), its hello function needs to be able to take any object of type A. A hello function which only takes objects of type B, rather than any A, is more restrictive. It can't play the role of A's hello function, so it's not an override.

如果你实验位在A和B上调用 hello ,传递类型A或B的对象,您应该能够看到差异。 A有一个函数取A(你没有定义,所以如果你调用它然后你的程序将无法链接,但你可以修复)。 B有一个函数取一个B.他们碰巧有相同的名字,当然,因为B从A派生,你可以传递一个B给函数取A。但B的函数不作为虚拟调用的覆盖。

If you experiment a bit with calling hello on A and B, passing objects of type A or B, you should be able to see the difference. A has a function taking an A (which you haven't defined, so if you call it then your program will fail to link, but you can fix that). B has a function taking a B. They happen to have the same name, and of course since B derives from A, you can pass a B to the function taking an A. But B's function doesn't act as an override in virtual calls.

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

It is possible to call A's function on a B object, but only via a reference or pointer to A. A feature of C++ is that the definition of hello in B hides the definition in A. If overloading is what you want, it's possible to un-hide the base class function by adding using A::hello; to class B. If overriding is what you want, you have to define a function taking the same parameters. For example:

#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
}

输出: p>

Output:

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


$ b b

如果你使用A :: hello; 从B中取出,那么调用 b.hello(a) code>无法编译:

If you take away the using A::hello; line from B, then the call b.hello(a); fails to compile:

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

这篇关于虚函数和多态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆