关于c ++:继承自std :: basic_string ok?

Is inheriting from std::basic_string ok?

本问题已经有最佳答案,请猛点这里访问。

我在这里读过许多类似的问题,但我仍然不确定答案。我知道不鼓励从stl类派生,但std::basic_字符串似乎是一个很好的候选者。

我面临的问题是G++抛出了一个fit,因为std::basic_字符串没有虚拟析构函数。为什么它不是虚拟的?std::string不是从中派生出来的吗?

一次尝试:

1
2
3
4
5
6
7
8
9
10
11
12
13
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() {}
};

另一次尝试:

1
2
3
4
5
6
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类并没有被设计成继承的。继承std::string和其他方法的主要问题是它们没有虚拟析构函数。对于公共继承的基类来说,这是一个很大的禁忌,正如警告所表明的那样。不过,这对私人继承来说并没有那么危险。

在私有继承具有非虚拟析构函数的基类的情况下,有一个错误报告没有发出错误。它没有被标记为Fixed,但是我的测试显示在带有私有继承的G++4.9.2中没有发出任何警告。

此外,该bug中的一条评论还展示了如何用(故意的?)射击自己的脚。坏代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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();
}

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

Doesn't std::string derive from it?

不,std::stringstd::basic_string的别名。