Oh Lord! What have you done?! This is a friendly advice, but before you go any further in the realm of virtual functions, you should go back and review how structures/classes and inheritance work. I am sorry to burst your bubble, but you didn't beat the compiler. With a few modifications, I managed to compile your first code, even the destructors were called, so let's go through this.
struct Wolf1 {
virtual void eat()=0;
Wolf1() {
std::cout<<"CONSTR1"<<std::endl;
ptr=this;
ptr->eat(); //Here you program will crash (you can comment this)
}
~Wolf1() {
std::cout<<"DECONSTR1"<<std::endl;
}
} *ptr; In the constructor you have the line : "ptr=this", if you leave that alone as it is now, it won't compile. The reason why not, is because ptr doesn't really exist in the scope of your structure(nor you have any valid global variables named ptr). If you look at 'ptr' closely you will see, that it has no type. You just made ptr up, therefore you cannot assign any value to it, yet alone use it. In that context, the following line : ptr->eat () simply wouldn't make any sense to the compiler.
Now you probably think, but I have *ptr. Yes, but that is not going to work either. First of all *ptr is not in the scope of your structure, so you wouldn't be able to use it anyway. I don't know how to put this, but when you define your class or your structure, you don't need an actual instance of the class you are defining. It's like a blueprint, you don't need to build an actual car, in order to design, and define how you want it to behave. Your class/structure definition should work the same way. I can see you are familiar with the pointer 'this'. That pointer serves that exact purpose, so you can refer to the class itself without a need of an actual instance.(When you make an instance of the class it becomes an object.)
Back to *ptr, what you really did there is you made a pointer of structure Wolf1. *ptr is not an instance of your structure. It is a pointer because you put the asterisk before ptr. Don't let the structure definition confuse you, you are basically saying "int *p", there is really nothing new going on.
You may ask yourself but how Wolf2 can compile without an error, if ptr does not really exist. Let's look at structure Wolf2.
Wolf2() {
std::cout<<"CONSTR2"<<std::endl;
ptr->eat();
} If you comment the line : "ptr->eat ()" out, it compiles. The reason why, is because you defined *ptr somewhere before structure Wolf2, therefore it exist in the scope of Wolf2. That is why you won't get an error there, however just because the compiler can make some sense of it, does not necessarily make it right. In Wolf2 you are calling "ptr->eat ()", but sadly *ptr is a pointer that has never been initialized. So when you call it, your program will crash, because ptr does not really point to anything. If you comment that line out your program will return 0, and even the destructors will be called. However this does not fix your code, it's still a mess. In your second code, you will need to address those issues. I really hope my analysis wasn't entirely futile, and now you can better understand what is really going on.