3

When I was working on a project that involved defining sentences in a given language, I was surprised to discover that std::string destructor was not virtual. This made it a lot more difficult to specialize this class (I had to create a wrapper). Why did the standard committee decide to have this class not virtual?

in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.5.3/include/g++-v4/bits/basic_string.h, we have:

template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string
{
   ...

  /**
   *  @brief  Destroy the string instance.
   */
  ~basic_string()
  { _M_rep()->_M_dispose(this->get_allocator()); }
qdii
  • 12,505
  • 10
  • 59
  • 116
  • maybe it's like in Java: the designers didn't want the programmer to extend the String class, as others programmer just expect the String to work with the standard implementation, not with some user defined (and malicious?) behavior. – Lorenzo Pistone Feb 03 '12 at 21:11

2 Answers2

9

It is by design. I think the designer is hinting that the class should not be sub-classed.

Also look at this: Why should one not derive from c++ std string class?

Community
  • 1
  • 1
Sid
  • 7,511
  • 2
  • 28
  • 41
  • 1
    I can tell you that at the organization I used to work in we did derive a String class from std::string following the rule that the derived String is not to ever contain any data-members but to be enhanced with methods such as strip() and split() as they are quite handy. It worked fine. Obviously a level of discipline is required to never put any data in this class. – Sid Feb 03 '12 at 21:18
  • @Sid: There's no need for that, though. Free-functions work just fine. – GManNickG Feb 03 '12 at 21:45
  • @GMan: Agreed. It was quite convenient though to be able to use split() strip() on the instance. Espc. having being used to Python. – Sid Feb 03 '12 at 21:54
  • @Sid: In Python you can also do `split = str.split; split("a b c")` ;) – UncleBens Feb 03 '12 at 21:59
  • @Sid: you need the further rule never to delete you derived thorough a pointer to base: even if there are no data members it is undefined behavior and can clobber the memory management system. – Dietmar Kühl Feb 03 '12 at 22:23
  • 1
    @Sid: and Python programmers are used to calling `len` as a (built-in) free function, so they should be able to cope with `split` being one. It's pretty arbitrary, and the more languages you know the less you care about what "the same line" of code looks like in different languages. Just as long as it's short and clear, I mean: obviously you care deeply about the differences that actually make a difference... – Steve Jessop Feb 03 '12 at 22:33
  • @DietmarKühl Thanks. I can't believe I was unaware of this. – Sid Feb 03 '12 at 23:05
  • @SteveJessop It wasn't about making it look just like Python. More about wanting to use str.split() rather than split(str). IMHO str.split() is more elegant. But your point well taken. – Sid Feb 03 '12 at 23:06
4

It's not meant to be derived from. None of the standard classes are.

The approved way to enhance them is by encapsulation, not inheritance.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 3
    "*The approved way to enhance them is by encapsulation, not inheritance.*" Or with simple free functions. – ildjarn Feb 03 '12 at 21:13
  • Some IO streams classes and all standard exceptions have `virtual` dtors. – Fred Foo Feb 03 '12 at 21:14
  • @larsmans: in the case of streams, they were designed pretty much independently of containers and `string`, and different decisions were made. So streams are designed for dynamic polymorphism, and containers (and strings) are not. I don't know why the exceptions have virtual destructors, though, I don't think I've ever `delete`d an exception in my life. – Steve Jessop Feb 03 '12 at 22:30
  • @larsmans: all classes in the standard library having a virtual destructor are either meant to be derived from or there are derived classes in the standard library. That the `std::ios_base` has a virtual destructor is my "fault": originally it didn't have a virtual destructor but I insisted that it gets on. Still, the classes derived thereof aren't really polymorphic: the polymorphic behavior mainly comes from `std::streambuf`. – Dietmar Kühl Feb 03 '12 at 22:34
  • 1
    @SteveJessop: The exception have the virtual function `what()` anyway: there is **no** harm in making them virtual but there is removed danger of erors. – Dietmar Kühl Feb 03 '12 at 22:43