C++ 函数覆盖
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1027724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ function overriding
提问by Mizipzor
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):
然后我从这样的基础推导出(用 X 代替 A、B 或 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).
- 使用 BaseA,子类不会编译,也不会定义纯虚函数。
- 使用 BaseB,在 BaseB* 或 Child* 上调用 foo 时会调用 child 中的函数。
- 使用BaseC,在Child* 上调用foo 时会调用子类中的函数,而在BaseB* 上则不调用(调用父类中的函数)。
采纳答案by Jared Oberhaus
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.
在派生类中,如果一个方法在基类中被定义为虚拟的,那么即使在派生类的方法中没有使用关键字 virtual 也是如此。
- With
BaseA
, it will compile and execute as intended, withfoo()
being virtual and executing in classChild
. - Same with
BaseB
, it will also compile and execute as intended, withfoo()
being virtual() and executing in classChild
. - With
BaseC
however, it will compile and execute, but it will execute theBaseC
version if you call it from the context ofBaseC
, and theChild
version if you call with the context ofChild
.
- 使用
BaseA
,它将按预期编译和执行,foo()
虚拟并在类中执行Child
。 - 与 相同
BaseB
,它也将按预期编译和执行,foo()
为 virtual() 并在 class 中执行Child
。 - 随着
BaseC
但是,它将编译并执行,但它会执行BaseC
,如果你从上下文中调用它的版本BaseC
,以及Child
版本,如果你用的情况下调用Child
。
回答by Todd Gardner
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).
要记住的重要规则是,一旦函数被声明为虚函数,在派生类中具有匹配签名的函数始终是虚函数。因此,它被 A 的孩子和 B 的孩子覆盖,它们的行为相同(除了您不能直接实例化 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)
但是,对于 C,该函数不会被覆盖,而是被重载。在那种情况下,只有静态类型很重要:它会根据它指向的指针(静态类型)而不是对象的真正含义(动态类型)来调用它
回答by Naveen
With BaseA, the child class doesn't compile, the pure virtual function isn't defined
使用 BaseA,子类不编译,纯虚函数未定义
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*
仅当您尝试创建 BaseA 的对象时,这才是正确的。如果您创建 Child 的对象,然后您可以使用 BaseA* 或 Child* 调用 foo()
With BaseB, the function in the child is called when calling foo on a BaseB* or Child*.
使用 BaseB,在 BaseB* 或 Child* 上调用 foo 时会调用 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.
取决于对象的类型,因为对象可以是 BaseB 或 Child。如果对象是 BaseB,则调用 BaseB::foo。
With BaseC, thefunction in the child is called when calling foo on Child* but not on BaseB* (the function in parent class is called).
使用BaseC,在Child* 上调用foo 时会调用子类中的函数,而在BaseB* 上则不调用(调用父类中的函数)。
Yes, but you never want to do this.
是的,但你永远不想这样做。
回答by stefaanv
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.
从多态的角度来看,更喜欢 A,所以你知道每个孩子都有自己的虚函数实现。
如果您有一个有效的默认实现,则主要选择 B,但是您必须确保所有子类根据需要都有自己的实现。C 不是多态性,因此请谨慎使用。
回答by Daniel
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.
它会调用 Child 的 foo 函数。
However, if you did this:
但是,如果您这样做:
BaseA baseA = new BaseA();
It would produce a compile time error.
它会产生编译时错误。
回答by Eric H.
Class Child willcompile if derived from A, you just can't instantiate objects of that type.
如果从 A 派生,则类 Child将编译,您只是无法实例化该类型的对象。
This might be valuable if you were going to override some functions from Base, and then derive again.
如果您打算从 Base 覆盖某些函数,然后再次派生,这可能很有价值。