The error is caused due to a call to A::decompose
in B and C destructors. The A::decompose
is called even if destructors are virtual and method is virtual itself. When A destructor is run for derived objects B or C, the derived part of the object was already destroyed.
class A {
public:
virtual void decompose() { std::cout << "A";}
virtual ~A() {
decompose();
}
};
class B:public A {
private:
int *b_data;
public:
void decompose() {
std::cout << "B";
if (b_data != NULL) delete [] b_data;
}
};
class C:public A {
private:
int *c_data;
public:
void decompose() {
std::cout << "C";
if (c_data != NULL) delete [] c_data;
}
~C() {}
};
int main(int argc, char** argv) {
B b;
C c;
return 0;
}
Output:
AA
Solution:
class A {
public:
virtual void decompose() = 0;
virtual ~A() {
std::cout << "~A";
}
};
class B:public A {
private:
int *b_data;
public:
void decompose() {
std::cout << "B_decompose"; if (b_data != NULL) delete [] b_data;
}
~B() { std::cout << "~B";}
};
class C:public A {
private:
int *c_data;
public:
void decompose() {
std::cout << "C_decompose"; if (c_data != NULL) delete [] c_data;
}
~C() { std::cout << "~C";}
};
int main(int argc, char** argv) {
B b;
C c;
A* p = &b;
p->decompose();
p = &c;
p->decompose();
return 0;
}