从std :: basic_string取消继承

时间:2013-01-31 16:04:35

标签: c++ inheritance stl stdstring

基本上,我有一个大型项目,它使用继承自c_string的自定义实用程序类std::basic_string<char>。由于种种原因,我想编辑这个类,以便

  1. 它不是来自std::basic_string<char>
  2. 我不必重新实现所有功能
  3. 我不必触及使用c_string
  4. 的每个文件

    所以我想改变:

    class c_string : public std::basic_string<char>
    {
    public:
        typedef std::basic_string<char> Base;
    
        c_string() : Base() {}
    }
    

    要:

    class c_string
    {
    
    ...
    
    public:
    
        ...
    
        c_string() {...}
    }
    

    所以,我想知道是否有人有一个很好的策略来做出这个改变,影响最小。

4 个答案:

答案 0 :(得分:2)

如果您的类在std::string上添加了自定义功能(您的项目需要),那么您运气不好:您必须封装std::string(并实现所有方法转发到{ {1}}实施)或继承自std::string(继承自std::string通常不是一个好主意。)

如果您的课程没有在std::string上添加额外的功能,请将std::string替换为class c_string { ... }

答案 1 :(得分:1)

您可以做的另一件事就是使用私有继承来更改公共继承。这样做会导致一堆编译错误,因为所有字符串的成员函数现在对您的类的客户端都是私有的。然后,您可以有选择地公开这些:

class my_string: std::string {
public:
    typedef std::string base; // convenience
    using base::const_iterator;
    using base::begin;
    using base::end;
};

你应该理解私有派生不是“my_string是一个std :: string”,而是“my_string是用std :: string实现的”。这种技术避免了从一个不打算成为基类的类型派生的一些缺点(隐式转换,切片等),比如std :: string。进行这种转换很容易,只需要几乎没有破坏任何东西的风险。之后,您可以控制转发的接口,这使转换和重构变得更加容易。

答案 2 :(得分:0)

我看不出任何方法可以避免至少包装所有功能。最直接的方法是拥有一个私有的basic_string成员,并且只编写在该成员上调用相同函数的包装器。

答案 3 :(得分:0)

我和zdp几乎有同样的问题。在很多代码中不继承std :: string导致不使用方法(我们有很多这样的)作为void Foo(string&amp; s_),其中字符串是函数中的参数,用户将my_string放入美孚()。简而言之:从std :: string继承,您可以将my_string发送到任何以my_string或std :: string作为参数的函数。 我想重写我的my_string类,但是在其他人手中有很多代码存在这个问题,很多人也不得不改变他们的代码。 一个糟糕的选择14年前....... sh ..