I ran across this example while studying early binding vs late binding, and I'm realizing that I really have no idea how compiling really works.
Here, the output is "Instrument::play", even though it really should be "Wind::play", but this can be changed by making the function Instrument::play a virtual function.
I can clearly see that the object flute is a Wind object, not an Instrument object. Would I be wrong in assuming that the compiler would know this as well? I mean, I figure compilers would always type-check function parameters, so in this case, wouldn't it check to see if an appropriate Instrument object was used, see that it's a Wind object, and automatically select the Wind version of play()?
#include <iostream>
using namespace std;
enum note { middleC, Csharp, Eflat }; // Etc.
class Instrument {
public:
  void play(note) const {
    cout << "Instrument::play" << endl;
  }
};
class Wind : public Instrument {
public:
  
  void play(note) const {
    cout << "Wind::play" << endl;
  }
};
void tune(Instrument i) {
  i.play(middleC);
}
int main()
{
  int a = 1+1;
  Wind flute;
  tune(flute);
}
 
     
    