我正在学习C++形式Thinking in C++ V1.我遇到了一个证明继承的例子.在这里
#include <iostream>
class Instrument{
public:
virtual void play(){
std::cout<<"instrument::play()";
}
};
class Wind: public Instrument{
public:
void play(){
std::cout<<"Wind::play()";
}
};
void tune(Instrument& i){
i.play();
}
int _tmain(int argc, _TCHAR* argv[])
{
Wind flute;
tune(flute);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这Wind::play()在控制台上输出.
但是,如果我将方法'tune'更改为
void tune(Instrument i){
i.play();
}
Run Code Online (Sandbox Code Playgroud)
输出会 instrument::play()
由于添加了'&'以便传递长笛的参考而不是副本,为什么程序输出instrument::play()而不是Wind::play()?
C++中对象表达式的多态行为由其动态类型决定.
当附加一个参考类型的Instrument &i到类型的对象Wind,通过引用的对象的动态类型i被保留.即i使用类型声明Instrument,它实际上指的是类型的实际对象Wind.这就是为什么i继续表现为Wind.如果使用指针引用某个对象,情况也是如此.
在正式的语言来说,它意味着静态类型表达的i是Instrument,但动态类型,如果同样的表达Wind.出于这个原因,i表现为多态的Wind.
同时,当您为类型值赋值(或初始化)对象Instrument i时Wind,您将创建一个独立的独立对象i类型Instrument.这个对象的类型是Instrument.因此,独立副本的i行为与Instrument所有多态上下文相同.
再次,用正式语言说,这意味着在这种情况下,静态类型和动态类型的表达式i都是Instrument.出于这个原因,i表现为多态的Instrument.
在C++语言中,"保留"对象的动态类型的唯一方法是使用指针或引用来引用该对象."Refer"是这里的关键词:您不创建新对象,而是 引用已存在的对象.并且那些现有对象继续按照其原生类型行事.类型的对象Wind继续表现为类型的对象Wind.(请注意,这仅适用于多态行为,例如,如何解析虚函数调用.)
但是,无论何时创建对象的独立副本(而不是引用原始对象),该副本都会获得自己的生命,具有自己的类型和相关属性.类型的独立副本Instrument与原始Wind对象无关.它没有记忆它作为一个Wind对象的副本诞生的事实.它表现得像Instrument.