C++ function overriding

2020-02-24 18:29发布

I have three different base classes:

class BaseA
{
public:
    virtual int foo() = 0;
};

class BaseB
{
public:
    virtual int foo() { return 42; }
};

class BaseC
{
public:
    int foo() { return 42; }
};

I then derive from the base like this (substitute X for A, B or C):

class Child : public BaseX
{
public:
    int foo() { return 42; }
};

How is the function overridden in the three different base classes? Are my three following assumptions correct? Are there any other caveats?

  • With BaseA, the child class doesn't compile, the pure virtual function isn't defined.
  • With BaseB, the function in the child is called when calling foo on a BaseB* or Child*.
  • With BaseC, the function in the child is called when calling foo on Child* but not on BaseB* (the function in parent class is called).

6条回答
beautiful°
2楼-- · 2020-02-24 19:15

In the derived class a method is virtual if it is defined virtual in the base class, even if the keyword virtual is not used in the derived class's method.

  • With BaseA, it will compile and execute as intended, with foo() being virtual and executing in class Child.
  • Same with BaseB, it will also compile and execute as intended, with foo() being virtual() and executing in class Child.
  • With BaseC however, it will compile and execute, but it will execute the BaseC version if you call it from the context of BaseC, and the Child version if you call with the context of Child.
查看更多
不美不萌又怎样
3楼-- · 2020-02-24 19:18

With BaseA, the child class doesn't compile, the pure virtual function isn't defined

This is true only if you try to create an object of BaseA. If you create a object of Child and then you can call foo() using either BaseA* or Child*

With BaseB, the function in the child is called when calling foo on a BaseB* or Child*.

Depends upon the type of the object as the object can be either BaseB or Child. If the object is BaseB then BaseB::foo is called.

With BaseC, thefunction in the child is called when calling foo on Child* but not on BaseB* (the function in parent class is called).

Yes, but you never want to do this.

查看更多
叼着烟拽天下
4楼-- · 2020-02-24 19:20

The important rule to remember is once a function is declared virtual, functions with matching signatures in the derived classes are always virtual. So, it is overridden for Child of A and Child of B, which would behave identically (with the exception of you can't directly instantiate BaseA).

With C, however, the function isn't overridden, but overloaded. In that situation, only the static type matters: it will call it on what it is a pointer to (the static type) instead of what the object really is (the dynamic type)

查看更多
仙女界的扛把子
5楼-- · 2020-02-24 19:24

Class Child will compile if derived from A, you just can't instantiate objects of that type.

This might be valuable if you were going to override some functions from Base, and then derive again.

查看更多
戒情不戒烟
6楼-- · 2020-02-24 19:25

From a polymorphism point of view, prefer A, so you know each child has his own implementation of the virtual function.
Choose B mainly if you have a valid default implementation, but then you have to make sure that all child-classes have their own implementation as needed. C is not polymorphism, so use judiciously.

查看更多
啃猪蹄的小仙女
7楼-- · 2020-02-24 19:32

It mostly depends on how you called it.

if you did:

class Child : public BaseA
{
public:
    int foo() { return 42; }
};

and did

BaseA baseA = new Child();
baseA->foo();

It would call Child's foo function.

However, if you did this:

BaseA baseA = new BaseA();

It would produce a compile time error.

查看更多
登录 后发表回答