从 std::basic_string 继承可以吗?

Is inheriting from std::basic_string ok?

我在这里阅读了很多类似的问题,但我仍然不确定答案。我知道不鼓励从​​ STL 类 派生,但 std::basic_string 似乎是一个不错的选择。

我面临的问题是 g++ 不合适,因为 std::basic_string 没有虚拟析构函数。为什么不是虚拟的? std::string不是从中推导出来的吗?

一次尝试:

class string_t :
  private std::basic_string<char>
{
public:
   string_t() :
      basic_string<value_type>() {}

   string_t(
      const basic_string<value_type>& s) :
         basic_string<value_type>(s) {}

   virtual ~string_t() {}
};

另一次尝试:

class string_t :
   public std::basic_string<char>
{
public:
   virtual ~string_t();
};

在使用 -Weffc++ 编译时都抛出此警告:

warning: base class 'class std::basic_string' has a non-virtual destructor

好吧,STL classes 并没有被设计成被继承。继承 std::string 和其他人的主要问题是它们没有虚拟析构函数。对于 public 的基础 class 继承来说,这是一个很大的禁忌,正如警告所表明的那样。不过,私有继承的危险性几乎没有。

有一个 bug report for not issuing an error in the case of privately inheriting a base class that has nonvirtual destructor. It hasn't been marked fixed, however my test shows that no warning is issued in g++ 4.9.2 具有私有继承。

此外,错误中的评论显示了如何用(故意的?)错误代码来攻击自己:

class Foo {
public:
    ~Foo() {}
    virtual void f() { }
};

class Bar : private Foo {
public:
    Foo* get() { return this; }
};

int main()
{
    Bar* b = new Bar;
    delete b->get();
}

如果您避免像上面的代码片段那样在 class 之外公开继承关系,那么使用非虚拟析构函数私下继承 class 也不错。如果不详细说明您将如何使用继承,就不可能说这是否是最好的方法。

Doesn't std::string derive from it?

不,std::stringstd::basic_string<char> 的别名。