I made mini code to just demonstrate what is my problem. So if an object is created and if initialization goes wrong, then the whole object will be deleted (derived and base class together). Ok, so there is no error with it, but when I call base's testBase function, there is no error. Does it mean that base class isn't destroyed or what?
Using an object that no longer exist is not guaranteed to crash or give an error. Instead it results in something called undefined behaviour which means anything is allowed to happen. Your program might crash but you should not rely on it.
One reason why t->testBase() happens to work for you might be that it doesn't access any of the object's data. t->testDerived() on the other hand needs to look at the object's so called vtable in order to decide which version of testDerived() to call.
There would be a memory leak if the constructor didn't fail because you never delete the object in main, but the big problem is that you have no way of checking if the object creation succeeded or not. The normal way of handling failing constructors (and other failing functions) is to use exceptions.
#include <iostream>
#include <stdexcept>
class Base {
std::string data_;
public:
Base() = default;
Base(std::string name) : data_(name) {
// Throw an exception to signal that the constructor failed.
throw std::runtime_error("Base constructor failed.");
}
virtual ~Base() = default;
void testBase() {
std::cout << "sign.";
std::cin.get();
}
virtualvoid testDerived() = 0;
};
class Derived : public Base {
public:
Derived() : Base("test") {
// No need to do anything special here to handle Base constructor failing.
}
~Derived() {}
void testDerived() {
std::cout << "sign.";
std::cin.get();
}
};
int main() {
try {
Base* t = new Derived;
// These functions will only be called if no exception was thrown.
t->testBase();
t->testDerived();
delete t;
}
catch (const std::exception& e) {
// The execution will continue from here if an exception is thrown
// inside the try block, otherwise this code will not run.
std::cout << "Error: " << e.what() << "\n";
}
return 0;
}