【问题标题】:Un-inherit from std::basic_string从 std::basic_string 取消继承
【发布时间】:2013-01-15 19:15:31
【问题描述】:

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

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

所以我想改变:

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

    c_string() : Base() {}
}

收件人:

class c_string
{

...

public:

    ...

    c_string() {...}
}

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

【问题讨论】:

  • 那么你为什么不想从basic_string派生?是不是标题把你搞砸了?
  • @NathanMonteleone:标准库类型并不意味着继承,至少不是公共继承......
  • @NathanMonteleone 我的情况的明显问题是从 v90(工作)到 v100 编译器导致 npos 在链接时成为未解析的外部符号
  • @zdp 你也许可以解决这个问题。是在抱怨 basic_string::npos 还是 c_string::npos?

标签: c++ inheritance stl stdstring


【解决方案1】:

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

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

【讨论】:

  • 如果您使用 C++11,则使用别名模板。
【解决方案2】:

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

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)派生的一些缺点(隐式转换、切片等)。进行这种转换很容易,它只是工作,几乎没有破坏任何东西的风险。之后,您可以控制转发的接口,这使得转换和重构变得更加容易。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2015-06-13
        • 1970-01-01
        • 2015-07-23
        • 1970-01-01
        • 1970-01-01
        • 2017-03-10
        • 1970-01-01
        • 2021-04-07
        • 2019-05-22
        相关资源
        最近更新 更多