I was told on this forum, I have read it in the books, and there are other answers stating that it is never good to inherit STL containers, because of the STL container destructors are not virtual (undefined behavior when deleting a derived object via base class pointer).
However, the C++11 standard now allows a design-by-contract checking at compile time, with member function specifiers, like delete
. I can fully understand why inheriting an STL container with a goal to extend with one member function or two is better replaced with coding the member functions as algorithms. Still, I have a situation where I model a collection of elements as a Concept, and the elements themselves are containers of other elements. I need to implement bidirectional iterators that access sub-element data Forward Iterator (e.g. Collection::sub_element_iterator). Using composition forces me in this case, to re-type (adapt) the entire std::vector public interface, only to extend this new Collection with an iterator.
Is in this scenario o.k if I still use inheritance, and prevent heap allocation in the following way?
Here is a small model of this:
#include <vector>
class not_heap_allocable
{
public:
void* operator new (std::size_t count) = delete;
};
template
<
typename Type,
template <typename T> class Allocator = std::allocator
>
class extended_vector
:
public std::vector<Type, Allocator<Type>>,
public not_heap_allocable
{
public:
typedef std::vector<Type> BaseType;
using BaseType::BaseType;
};
using namespace std;
int main(int argc, const char *argv[])
{
vector<int>* vNew = new extended_vector<int> ({0,1,2,3,4,5}); // Compile time error.
return 0;
}
Which then results in a compile-time error:
main.cpp: In function ‘int main(int, const char**)’:
main.cpp:31:64: error: use of deleted function ‘static void* not_heap_allocable::operator new(std::size_t)’
vector<int>* vNew = new extended_vector<int> ({0,1,2,3,4,5}); // Compile time error.
^
main.cpp:6:15: error: declared here
void* operator new (std::size_t count) = delete;
As a result, the extended_vector
is no longer counting on humans not to misuse it.