[英]static and dynamic resolution in C++
我关注的文本是:
使用对象对虚拟函数的调用始终是静态解决的。 您只能通过指针或引用获得动态分辨率。
现在考虑以下程序:
#include <iostream>
class Mainclass{
protected:
double length{1.0};
double width{1.0};
double height{1.0};
public:
Mainclass(double lv, double wv, double hv):length{lv}, width{wv}, height{hv}{
std::cout<<"Three args box ran"<<std::endl;
}
void showVolume() const{
std::cout<<"Mainclass usable volume is: "<<Volume()<<std::endl;
}
virtual double Volume() const{
return length*width*height;
}
};
class Derivedclass: public Mainclass{
public:
Derivedclass(double lv, double wv, double hv): Mainclass{lv, wv, hv}{}
double Volume() const{
return 0.85*length*width*height;
}
};
int main(){
Mainclass first{20.0, 30.0, 40.0};
Derivedclass second {20.0, 30.0, 40.0};
first.showVolume();
second.showVolume();
}
输出:
Three args box ran
Three args box ran
Mainclass usable volume is: 24000
Mainclass usable volume is: 20400
在这里,我通过基类对象和派生类对象的对象实例而不是指针来调用它们。 但似乎该功能正在动态解析。 文字有误吗? 如果不是,那是什么意思?
“使用对象对虚拟函数的调用始终是静态解决的。您只能通过指针或引用来获得动态解析。”
这句话不是描述C ++语言的规则,而是允许编译器采用快捷方式。
您直接在对象名称上调用showFunction
。 因此,假设showFunction
被声明为虚拟的。 编译器知道称为first
和second
的对象的确切类型:根本不可能使它们成为其他类型的对象。 因此,尽管该语言说任何覆盖函数都必须由first.showVolume()
和second.showVolume()
调用,但是除了编译器可以立即找到的函数外,结果不可能是任何其他函数,因此实际上并没有需要放置任何代码来确定要在结果程序中调用哪个函数。 可以直接调用正确的函数Mainclass::showVolume()
(或Derivedclass::showVolume()
(如果存在)),这样可以稍微提高效率。
该引用不适用于showVolume()
内部的Volume()
的调用。 由于Volume
命名为非静态成员,因此Volume()
含义与this->Volume()
。 this
是一个指针,它可能会或可能不会指向其完整类型与指针的Mainclass* const
类型匹配的对象。 因此,在这种情况下,要求编译器进行动态解析以确定要调用的函数。
但是还有一点要注意:确实只能通过指针或引用获得动态分辨率,但事实并非如此,您始终可以通过指针或引用获得动态分辨率。 当使用::
标记将函数命名为“合格ID”时,该语言表示被调用的函数是静态确定的,并且覆盖将被忽略。 例如,如果showVolume()
代码更改为使用Mainclass::Volume()
或this->Mainclass::Volume()
,则您将看到它从未调用Derivedclass::Volume
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.