In the code below I have one UserInterface shared_ptr obj, but when the program finished its destructor is called multiple times as in the output below:
finishing...
Destroying UserInterface
Destroying InterfaceElement Submit button
Destroying UserInterface
Destroying InterfaceElement Spouse's name textbox
Destroying UserInterface
Destroying InterfaceElement Is married checkbox
Destroying UserInterface
Destroying InterfaceElement Name textbox
Destroying UserInterface
free(): double free detected in tcache 2
Aborted
I was expecting the “Destroying UserInterface” message to be displayed only once since I only got the ui
reference. Why does this happen?
#include <iostream>
#include <memory>
using std::string, std::shared_ptr, std::cout, std::unique_ptr;
class Mediator {
public:
virtual void mediate(const string& event) = 0;
};
typedef shared_ptr<Mediator> mptr;
class InterfaceElement {
protected:
mptr mediator;
string name;
bool isVisible = true;
public:
InterfaceElement(const string& name, bool isVisible, mptr mediator) : name(name), isVisible(isVisible), mediator(mediator) {};
~InterfaceElement(){
cout << "Destroying InterfaceElement " << name << "n";
}
};
class ButtonElement : public InterfaceElement {
// similar to class CheckBox
};
class TextBox : public InterfaceElement {
// similar to class CheckBox
};
class CheckBox : public InterfaceElement {
bool isChecked = false;
public:
CheckBox(const string& name, bool isVisible, mptr mediator) : InterfaceElement(name, isVisible, mediator) {};
virtual ~CheckBox() {};
virtual void setIsChecked(bool isChecked) {
this->isChecked = isChecked;
if (isChecked) {
mediator->mediate(name + " is checked");
} else {
mediator->mediate(name + " is unchecked");
}
};
};
class UserInterface : public Mediator {
shared_ptr<TextBox> nameTextBox;
shared_ptr<CheckBox> isMarriedCheckbox;
shared_ptr<TextBox> spousesNameTextBox;
shared_ptr<ButtonElement> submitButton;
public:
UserInterface() {
nameTextBox = shared_ptr<TextBox>(new TextBox("Name textbox", true, shared_ptr<Mediator>(this)));
isMarriedCheckbox = shared_ptr<CheckBox>(new CheckBox("Is married checkbox", true, shared_ptr<Mediator>(this)));
spousesNameTextBox = shared_ptr<TextBox>(new TextBox("Spouse's name textbox", false, shared_ptr<Mediator>(this)));
submitButton = shared_ptr<ButtonElement>(new ButtonElement("Submit button", false, shared_ptr<Mediator>(this)));
}
~UserInterface() {
cout << "Destroying UserInterfacen";
}
void mediate(const string& event) override {
cout << "Mediating event: " << event << "...n";
}
shared_ptr<TextBox> getNameTextBox() { return nameTextBox; };
shared_ptr<CheckBox> getIsMarriedCheckbox() { return isMarriedCheckbox; };
shared_ptr<TextBox> getSpousesNameTextBox() { return spousesNameTextBox; };
shared_ptr<ButtonElement> getSubmitButton() { return submitButton; };
};
typedef unique_ptr<UserInterface> uiptr;
int main(int argc, const char * argv[]) {
uiptr ui = uiptr(new UserInterface);
cout << "finishing...n";
return 0;
}