Nel "Programma B" è vero che alla funzione whichPhoneUserIsUsing(...) passiamo per valore il parametro che ha come tipo la classe base, ma non penso che il compilatore risolva il binding a compile-time. Infatti nel ProgrammaB la funzione which() della classe base è comunque dichiarata virtual, quindi se non mi sbaglio, anche se il parametro lo passiamo per valore, viene in ogni caso consultata la virtual table per la scelta della funzione da eseguire a runtime. Il problema semmai è che il costruttore di copia, vedendo che la funzione si aspetta come parametro un oggetto della classe base, allocherà uno spazio in memoria per contenere un oggetto di quel tipo, anche se poi andiamo a passare un oggetto di una sottoclasse quando la funzione viene chiamata. In questo caso verrà fatto una specie di casting fra il parametro formale nel legame con quello attuale, che porterà in ogni caso l'oggetto devices ad avere come tipo la classe base. Ed è questo che porterà, a runtime, alla scelta della funzione which() della classe base piuttosto che quella della sottoclasse come ci saremmo aspetti (e come sarebbe avvenuto se avessimo passato il parametro per riferimento come nel Programma A). Scusatemi in anticipo se ho detto qualche imprecisione.