[英]Understanding Inheritance and functions with different signatures
Say I have a base class and a derived class. 说我有一个基类和一个派生类。
class Base {
public:
void A(int x, int y) {do something}
void B() {
A(x,y);
do something;
}
};
class Derived : public Base {
void A() {do something else};
};
Derived derived1;
derived1.B();
The signatures of the functions are different, will the B call the derived A or the base A? 函数的签名不同,B会调用派生的A还是基数A? Iif it will call the derived B, I guess it will dismiss the parameters? 如果它会调用派生的B,我猜想它将取消该参数吗?
what if the derived A needed different parameters rather than no parameters, would I have to copy B's entire code into the derived class just to change the way B calls A? 如果派生的A需要不同的参数而不是没有参数怎么办,我是否必须将B的整个代码复制到派生的类中,以改变B调用A的方式?
A function's code is always evaluated in the context of the class in which it is defined. 函数代码始终在其定义的类的上下文中进行评估。 This includes determining which function each expression calls. 这包括确定每个表达式调用哪个函数。 So inside Base::B()
, the call A(x, y)
is translated by the compiler as a call to Base::A
. 因此在Base::B()
内部,调用A(x, y)
被编译器转换为对Base::A
的调用。 Even if you later call derived1.B()
, it will call derived1 . Base::A
即使您以后调用derived1.B()
,它也会调用derived1 . Base::A
derived1 . Base::A
(pseudo-syntax). derived1 . Base::A
(伪语法)。
The only thing which changes this slightly is virtual functions. 仅有一点改变的是虚函数。 However, even with them, the rules are similar. 但是,即使有了它们,规则也是相似的。 Overload resolution (which is basically the process of matching a function name & signature to a call expression) is done in the context of the class where the containing function is defined. 重载解析(基本上是将函数名称和签名与调用表达式匹配的过程)是在定义包含函数的类的上下文中完成的。 If the resolution leads to a virtual function being selected, the virtual call mechanism will then be invoked at runtime to call the appropriate override of that function. 如果解决方案导致选择了虚拟函数,则将在运行时调用虚拟调用机制以调用该函数的适当替代。
Let's consider this example: 让我们考虑这个例子:
struct Base {
virtual void foo(int);
virtual void bar() { foo(0.0); }
};
struct Derived : Base {
virtual void foo(int);
virtual void foo(double);
};
Derived d;
d.bar();
Even in this example, calling d.bar()
will call Derived::foo(int)
. 即使在此示例中,调用d.bar()
也会调用Derived::foo(int)
。 That's because the call-to-signature matching was done in the context of Base
, which only sees foo(int)
and employs the implicit conversion from double
to int.
这是因为调用签名匹配是在Base
上下文中完成的,后者仅看到foo(int)
并采用从double
到int.
的隐式转换int.
Two reasons force Base::B
to call Base::A
not Derived::A
迫使Base::B
调用Base::A
而不Derived::A
两个原因
A
with specific overload: A(int, int)
它以特定的重载调用A
: A(int, int)
Base::A
and Base::B
are not virtual, so it calls Base::A
. Base::A
和Base::B
不是虚拟的,因此它称为Base::A
The code is not polymorphic. 该代码不是多态的。 The simplest example to show a how a virtual method works is: 显示虚拟方法如何工作的最简单示例是:
class Base {
public:
virtual void A() {
// do job #1
}
};
class Derived : public Base {
public:
virtual void A() {
// do job #2
}
};
// ...
Derived derived1;
Base *base = &derived1;
base->A(); // <---- It calls `Derived::A()` and does job #2
But, if you write A
in B
with different parameter (overload it), you have to call it explicitly with actual arguments. 但是,如果用不同的参数在B
写A
(使它过载),则必须使用实际参数显式调用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.