Last active
January 11, 2018 05:09
-
-
Save jefferton/60a46ec014344ca04e96648535498a27 to your computer and use it in GitHub Desktop.
Compares the effect of delete-ing objects via base class pointer when the base class and/or child class lacks a virtual destructor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compares the effect of delete-ing objects via base class pointer | |
// when the base class and/or child class lacks a virtual destructor | |
#include <iostream> | |
#include <memory> | |
struct BaseMember | |
{ | |
BaseMember() { std::cout << "BaseMember()\n"; } | |
~BaseMember() { std::cout << "~BaseMember()\n"; } | |
}; | |
struct ChildMember | |
{ | |
ChildMember() { std::cout << "ChildMember()\n"; } | |
~ChildMember() { std::cout << "~ChildMember()\n"; } | |
}; | |
struct NonVirtual // <-------- NON-VIRTUAL DESTRUCTOR | |
{ | |
NonVirtual() { std::cout << "NonVirtual()\n"; } | |
~NonVirtual() { std::cout << "~NonVirtual()\n"; } | |
BaseMember bm; | |
}; | |
struct NonVirtualWithVirtualDestructor : NonVirtual | |
{ | |
NonVirtualWithVirtualDestructor() { std::cout << "NonVirtualWithVirtualDestructor()\n"; } | |
virtual ~NonVirtualWithVirtualDestructor() { std::cout << "~NonVirtualWithVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct NonVirtualWithNonVirtualDestructor : NonVirtual | |
{ | |
NonVirtualWithNonVirtualDestructor() { std::cout << "NonVirtualWithNonVirtualDestructor()\n"; } | |
~NonVirtualWithNonVirtualDestructor() { std::cout << "~NonVirtualWithNonVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct Virtual // <-------- VIRTUAL DESTRUCTOR | |
{ | |
Virtual() { std::cout << "Virtual()\n"; } | |
virtual ~Virtual() { std::cout << "~Virtual()\n"; } | |
BaseMember bm; | |
}; | |
struct VirtualWithVirtualDestructor : Virtual | |
{ | |
VirtualWithVirtualDestructor() { std::cout << "VirtualWithVirtualDestructor()\n"; } | |
virtual ~VirtualWithVirtualDestructor() { std::cout << "~VirtualWithVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct VirtualWithNonVirtualDestructor : Virtual | |
{ | |
VirtualWithNonVirtualDestructor() { std::cout << "VirtualWithNonVirtualDestructor()\n"; } | |
~VirtualWithNonVirtualDestructor() { std::cout << "~VirtualWithNonVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct PureVirtual // <-------- PURE VIRTUAL DESTRUCTOR | |
{ | |
PureVirtual() { std::cout << "PureVirtual()\n"; } | |
virtual ~PureVirtual() = 0; | |
BaseMember bm; | |
}; | |
PureVirtual::~PureVirtual() { std::cout << "~PureVirtual()\n"; } | |
struct PureVirtualWithVirtualDestructor : PureVirtual | |
{ | |
PureVirtualWithVirtualDestructor() { std::cout << "PureVirtualWithVirtualDestructor()\n"; } | |
virtual ~PureVirtualWithVirtualDestructor() { std::cout << "~PureVirtualWithVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct PureVirtualWithNonVirtualDestructor : PureVirtual | |
{ | |
PureVirtualWithNonVirtualDestructor() { std::cout << "PureVirtualWithNonVirtualDestructor()\n"; } | |
~PureVirtualWithNonVirtualDestructor() { std::cout << "~PureVirtualWithNonVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct DefaultVirtual // <-------- DEFAULT VIRTUAL DESTRUCTOR | |
{ | |
DefaultVirtual() = default; | |
virtual ~DefaultVirtual() = default; | |
BaseMember bm; | |
}; | |
struct DefaultVirtualWithVirtualDestructor : DefaultVirtual | |
{ | |
DefaultVirtualWithVirtualDestructor() { std::cout << "DefaultVirtualWithVirtualDestructor()\n"; } | |
virtual ~DefaultVirtualWithVirtualDestructor() { std::cout << "~DefaultVirtualWithVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct DefaultVirtualWithNonVirtualDestructor : DefaultVirtual | |
{ | |
DefaultVirtualWithNonVirtualDestructor() { std::cout << "DefaultVirtualWithNonVirtualDestructor()\n"; } | |
~DefaultVirtualWithNonVirtualDestructor() { std::cout << "~DefaultVirtualWithNonVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct EmptyVirtual // <-------- EMPTY VIRTUAL DESTRUCTOR | |
{ | |
EmptyVirtual() {} | |
virtual ~EmptyVirtual() {} | |
BaseMember bm; | |
}; | |
struct EmptyVirtualWithVirtualDestructor : EmptyVirtual | |
{ | |
EmptyVirtualWithVirtualDestructor() { std::cout << "EmptyVirtualWithVirtualDestructor()\n"; } | |
virtual ~EmptyVirtualWithVirtualDestructor() { std::cout << "~EmptyVirtualWithVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
struct EmptyVirtualWithNonVirtualDestructor : EmptyVirtual | |
{ | |
EmptyVirtualWithNonVirtualDestructor() { std::cout << "EmptyVirtualWithNonVirtualDestructor()\n"; } | |
~EmptyVirtualWithNonVirtualDestructor() { std::cout << "~EmptyVirtualWithNonVirtualDestructor()\n"; } | |
ChildMember cm; | |
}; | |
int main() | |
{ | |
std::cout << "-------- GOOD -----------------\n"; | |
{ | |
std::unique_ptr<Virtual> bcp(new VirtualWithVirtualDestructor()); | |
} | |
std::cout << "-------- GOOD -----------------\n"; | |
{ | |
std::unique_ptr<Virtual> bcp(new VirtualWithNonVirtualDestructor()); | |
} | |
std::cout << "-------- GOOD -----------------\n"; | |
{ | |
std::unique_ptr<PureVirtual> bcp(new PureVirtualWithVirtualDestructor()); | |
} | |
std::cout << "-------- GOOD -----------------\n"; | |
{ | |
std::unique_ptr<PureVirtual> bcp(new PureVirtualWithNonVirtualDestructor()); | |
} | |
std::cout << "-------- GOOD -----------------\n"; | |
{ | |
std::unique_ptr<DefaultVirtual> bcp(new DefaultVirtualWithVirtualDestructor()); | |
} | |
std::cout << "-------- GOOD -----------------\n"; | |
{ | |
std::unique_ptr<DefaultVirtual> bcp(new DefaultVirtualWithNonVirtualDestructor()); | |
} | |
std::cout << "-------- GOOD -----------------\n"; | |
{ | |
std::unique_ptr<EmptyVirtual> bcp(new EmptyVirtualWithVirtualDestructor()); | |
} | |
std::cout << "-------- GOOD -----------------\n"; | |
{ | |
std::unique_ptr<EmptyVirtual> bcp(new EmptyVirtualWithNonVirtualDestructor()); | |
} | |
std::cout << "-------- BAD -----------------\n"; | |
{ | |
std::unique_ptr<NonVirtual> bcp(new NonVirtualWithNonVirtualDestructor()); | |
} | |
std::cout << "-------- CRASH -----------------\n"; | |
{ | |
std::unique_ptr<NonVirtual> bcp(new NonVirtualWithVirtualDestructor()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment