Yes, I actually had seen this one, forgot it. The result of a strange combination in BlitzMax I guess:
1) allowing virtual method calls from the constructor
2) while still considering that in TBase.New , Self is a TBase and only a TBase even if you actually instanciate a TDerived (meaning the virtual table is set in two stage, first to the table of TBase - set before TBase.New() -, then to the table of TDerived - set before TDerived.New().
Right?
The easiest way to fix this would be keep (1), and change (2):
setup the TDerived virtual table just once, even before TBase.New executes.
In fact I would ahve thought that was what you were doing in the first place, this is as far as I understand how java handles it. Which is the exact opposite of what C++ does.
--start of digression--
If I'm not mistaken the equivalent c++ program shouldn't ever compile, or at least link.
class TBase {
public:
TBase() {
Test();
}
virtual void Test() = 0;
};
class TDerived : public TBase {
public:
void Test() {
std::cout <<"Test" << std::endl;
}
};
int main()
{
TDerived * obj = new TDerived;
return 0;
}The previous code snippet indeed doesn't link with my compiler. But fooling it is easy, as the following code snippet compiles and exhibits a pure virtual call when run. Note that this code is not legal C++ code as per the C++ standard, so anything could happen. The program could well make your computer play tha traviata and you couldn't blame the compiler.
class TBase {
public:
void Dummy() {
Test();
}
TBase() {
Dummy();
}
virtual void Test() = 0;
};
class TDerived : public TBase {
public:
void Test() {
std::cout <<"Test" << std::endl;
}
};
int main()
{
TDerived * obj = new TDerived;
return 0;
}--end of digression--