从std::basic_string继承正常

Is inheriting from std::basic_string ok?

本文关键字:继承 string std basic      更新时间:2023-10-16

我在这里读过很多类似的问题,但我仍然不确定答案。我知道不鼓励从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++编译时,两者都会抛出此警告:

警告:基类"class std::basic_string"具有非虚拟析构函数

好吧,STL类并没有被设计为可继承的。继承std::string和其他方法的主要问题是它们没有虚拟析构函数。正如警告所表明的那样,这对公共继承的基类来说是一个很大的禁忌。不过,这对私人继承来说并没有那么危险。

有一个错误报告,说明在私下继承具有非虚拟析构函数的基类的情况下没有发出错误。它还没有被标记为已修复,但我的测试显示,在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();
}

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

std::string不是派生自它吗?

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