I was trying to figure out with what signatures C++ actually calls methods virtually, instead of using the base class. So I wrote the following:
#include <iostream>
#include <string>
using namespace std;
#define GREETER(type, op)\
    string greet(type t) {\
        return string(#type) + t op greet();\
    }
struct Unvirtual {
    string greet() {
        return "Unvirtual";
    }
};
struct UnvirtualUnoverride : Unvirtual {
    string greet() {
        return "UnvirtualUnoverride";
    }
};
struct Virtual {
    virtual string greet() {
        return "Virtual";
    }
};
struct VirtualUnoverride : Virtual {
    virtual string greet() {
        return "VirtualUnoverride";
    }
};
struct VirtualOverride : Virtual {
    virtual string greet() override {
        return "VirtualOverride";
    }
};
GREETER(Unvirtual, .)
//GREETER(Unvirtual&, .)
GREETER(Unvirtual*, ->)
// GREETER(UnvirtualUnoverride, .)
// GREETER(UnvirtualUnoverride&, .)
// GREETER(UnvirtualUnoverride*, ->)
GREETER(Virtual, .)
//GREETER(Virtual&, .)
GREETER(Virtual*, ->)
// GREETER(VirtualUnoverride, .)
// GREETER(VirtualUnoverride&, .)
// GREETER(VirtualUnoverride*, ->)
// GREETER(VirtualOverride, .)
// GREETER(VirtualOverride&, .)
// GREETER(VirtualOverride*, ->)
#define DEBUG(expr)\
    cout << #expr << endl;\
    cout << "\t" << expr << endl;
int main() {
    Unvirtual uv, &uvr = uv, *uvp = &uv;
    UnvirtualUnoverride uvu, &uvur = uvu, *uvup = &uvu;
    Virtual v, &vr = v, *vp = &v;
    VirtualUnoverride vu, &vur = vu, *vup = &vu;
    VirtualOverride vo, &vor = vo, *vop = &vo;
    DEBUG(greet(uv));
    DEBUG(greet(uvr));
    DEBUG(greet(uvp));
    DEBUG(greet(uvu));
    DEBUG(greet(uvur));
    DEBUG(greet(uvup));
    DEBUG(greet(v));
    DEBUG(greet(vr));
    DEBUG(greet(vp));
    DEBUG(greet(vu));
    DEBUG(greet(vur));
    DEBUG(greet(vup));
    DEBUG(greet(vo));
    DEBUG(greet(vor));
    DEBUG(greet(vop));
    system("pause");
    return 0;
}
The program's output was:
greet(uv)
    UnvirtualUnvirtual
greet(uvr)
    UnvirtualUnvirtual
greet(uvp)
    Unvirtual*Unvirtual
greet(uvu)
    UnvirtualUnvirtual
greet(uvur)
    UnvirtualUnvirtual
greet(uvup)
    Unvirtual*Unvirtual
greet(v)
    VirtualVirtual
greet(vr)
    VirtualVirtual
greet(vp)
    Virtual*Virtual
greet(vu)
    VirtualVirtual
greet(vur)
    VirtualVirtual
greet(vup)
    Virtual*VirtualUnoverride
greet(vo)
    VirtualVirtual
greet(vor)
    VirtualVirtual
greet(vop)
    Virtual*VirtualOverride
Press any key to continue . . .
From this I conclude that C++ only dispatches method m on object o dynamically when: m is declared virtual and o is a pointer.
Are these conclusions accurate? Have I missed any tests?
 
     
     
    