C++ 函数重载

发布于 2024-07-25 08:26:07 字数 592 浏览 3 评论 0原文

我有三个不同的基类:

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

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

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

然后我像这样从基类派生(用 X 代替 A、B 或 C):

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

如何在三个不同的基类中重写该函数? 我的以下三个假设正确吗? 还有其他注意事项吗?

  • 对于 BaseA,子类无法编译,纯虚函数也未定义。
  • 对于 BaseB,当在 BaseB* 或 Child* 上调用 foo 时,会调用子进程中的函数。
  • 对于 BaseC,在 Child* 上调用 foo 时会调用子类中的函数,但在 BaseB* 上调用 foo 时不会调用(调用父类中的函数)。

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

别在捏我脸啦 2024-08-01 08:26:07

要记住的重要规则是,一旦函数被声明为虚函数,派生类中具有匹配签名的函数始终是虚函数。 因此,它被 A 的 Child 和 B 的 Child 覆盖,其行为相同(除了不能直接实例化 BaseA)。

然而,对于 C,该函数不是被重写,而是重载。 在这种情况下,只有静态类型很重要:它将根据指向的指针(静态类型)而不是对象的实际内容(动态类型)来调用它

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)

绅士风度i 2024-08-01 08:26:07

在派生类中,如果在基类中定义了 virtual 方法,则该方法是虚拟的,即使在派生类的方法中未使用关键字 virtual。

  • 使用BaseA,它将按预期编译和执行,其中foo()是虚拟的并在类Child中执行。
  • BaseB相同,它也会按预期编译和执行,其中foo()是virtual()并在类Child中执行。
  • 然而,使用 BaseC 时,它将编译并执行,但如果您从 BaseC 的上下文中调用它,它将执行 BaseC 版本,并且如果您使用 Child 上下文调用,则 Child 版本。

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.
画骨成沙 2024-08-01 08:26:07

使用 BaseA,子类不会
编译,纯虚函数
未定义

仅当您尝试创建 BaseA 的对象时,这才是正确的。 如果创建 Child 的对象,然后可以使用 BaseA* 或 Child* 调用 foo()

有了BaseB,子进程中的函数
在 BaseB* 上调用 foo 时被调用
或儿童*。

取决于对象的类型,因为对象可以是 BaseB 或 Child。 如果对象是 BaseB,则调用 BaseB::foo。

使用BaseC,子函数中
在 Child* 上调用 foo 时被调用
但不在 BaseB* 上(该函数在
调用父类)。

是的,但你永远不想这样做。

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.

生死何惧 2024-08-01 08:26:07

从多态性的角度来看,更喜欢 A,所以你知道每个孩子都有自己的虚函数实现。
如果您有有效的默认实现,则主要选择 B,但是您必须确保所有子类根据需要都有自己的实现。
C 不是多态性,因此请谨慎使用。

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.

我家小可爱 2024-08-01 08:26:07

这主要取决于你如何称呼它。

if you did:

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

and did

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

它将调用 Child 的 foo 函数。

但是,如果您这样做:

BaseA baseA = new BaseA();

它将产生编译时错误。

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.

金橙橙 2024-08-01 08:26:07

如果从 A 派生,子类编译,只是无法实例化该类型的对象。

如果您要重写 Base 中的某些函数,然后再次派生,这可能会很有价值。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文