virtualつけた関数ってどういう挙動なんですか

A←B←Cと継承してる場合
基底クラスからvirtualをずっとつけといた関数は
A *c=(A) new C; c->hoge(); とかやると
newしたときのクラスCのhoge()が呼ばれるけど
ずっとvirtualをつけてないときはAのhogeが呼ばれる。

で、よくわからないのが
継承の途中からvirtualをつけたり、途中からはずしたりしたとき。
実験しまくってるけど法則がよくわからないです。