CTest * obj = NULL;
Это НЕ то, как вы создаете объект в стеке. Вот как вы создаете указатель объекта в стеке и указываете в никуда.
Вы можете просто сделать:
CTest obj; // This creates the object, calls constructor
И поскольку объект обрабатывается как ссылка, а не указатель, вы можете использовать
obj.func();
obj.virtualFunc();
и т. Д.
Чтобы использовать указатель для переменной стека, вы можете сделать:
CTest obj_value; // This actually creates the object
CTest * obj = &obj_value; // This creates pointer to stack object
Нахождение объекта в стеке или в куче не влияет на поведениевиртуальные функции.
В вашем случае тот факт, что obj->func();
работает, а не segfault, на самом деле является неудачей. Методы не хранятся внутри объекта. Они хранятся в секции кода исполняемого файла, один раз для всей программы, а не экземпляра, как обычные функции. Они также переводятся в нечто вроде:
CTest::func(CTest * this) // here this is obj
И поскольку this
недопустимо, но не используется, ничего явно не происходит.
В случае виртуальных функций каждая виртуальная функциявызов функции фактически читает this
, чтобы получить то, что называется vtable
. Здесь происходит сбой вашей программы, так как this
является нулевым указателем.