Base class doesn't want to delete.

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?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
class Base {

	std::string data_;

	bool initialized = false;

public:

	Base() = default;

	Base(std::string name) : data_(name) {

		initialized = false;

	}

	virtual ~Base() = default;

	bool getInitialized() {

		return initialized;
	}

	void testBase() {

		std::cout << "sign.";
		std::cin.get();

	}

	virtual void testDerived() = 0;

};

class Derived : public Base {

public:

	Derived() : Base("test") {

		if (!getInitialized()) {

			Base* t = this;

			delete t;

		}

	}

	~Derived() {}

	void testDerived() {

		std::cout << "sign.";
		std::cin.get();

	}

};

int main() {

	Base* t = new Derived;

	t->testBase(); //it's working, but it shouldn't because it has to be NULL.
	t->testDerived(); //not working and it's good.

	return 0;
}


Thanks :)!
Last edited on
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.
Last edited on
So should I leave it or should I change something? Is there any memory leak? Thank you very much!
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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#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();

	}

	virtual void 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;
}

http://www.cplusplus.com/doc/tutorial/exceptions/
Last edited on
Topic archived. No new replies allowed.