typedef a std::string - 最佳实践

5
我正在使用标准C++编写一个音标转换库,目前我已经使用了std::string。但是在未来,我可能需要将其更改为其他类型(如std::wstring或其他类型)。因此,我需要以这样的方式编写我的库,以便可以轻松切换。到目前为止,我已经采取了以下措施来实现这一点。
  1. 创建一个头文件,该文件将被所有CPP文件使用
  2. 在其中添加“typedef std::string”,并在文件中的所有地方使用新名称。
如果我需要更改类型,我只需更改头文件中的内容即可反映到所有地方。如果有人能看一下这是否是正确的方法,或者是否有更好的方法来完成这个任务,我将不胜感激。
谢谢。
5个回答

5
您可以编写模板函数,以适用于任何具有适当方法的字符串类型,或者其他类型。
如果您按照建议进行typedef,则将来需要更改typedef时需要更改所有代码。我建议不要这样做。
编辑:关键是string和wstring不能互换使用。当然,您可以通过更改一行代码来更新库,但这只是开始-更改typedef意味着您正在更改库的公共API。您将不得不更改和测试所有与库交互的代码,这可能代表了大部分工作。甚至可能只需简单的搜索和替换即可更新库,然后typedef对您没有任何帮助。
坚持使用每个人都知道和理解的标准类型是有价值的。

谢谢。如何创建一个派生自std :: string的新类?如果我需要更改为另一种完全不同的类型,我可以更改继承并为此自定义类提供必要的接口方法,这可以用最少的努力完成。你怎么看? - Navaneeth K N
1
我不明白为什么模板方法比typedef更好。我的意思是,如果他改变了类型,他只需要改变typedef - 这毕竟是他想引入它的原因。 - Johannes Schaub - litb
@Appu:如果你想让你的代码具有可移植性,那么从std::string派生出来并不是一件容易的事情。原因是STL实现者可以根据需要为std::string添加任何可选模板参数。 - wilhelmtell
是的。我认为常规情况下,typedef 存在的目的就是为了抽象类型名称,以便您可以轻松地更改类型引用。当然,它们不能解决接口问题。 - wilhelmtell
字符串和宽字符串不可互换,但编译器会告诉你需要进行哪些更改。据我所知,在 char 和 wchar_t 类型之间没有自动转换,因此该事物将保持类型安全。这就是为什么我同意首先使用 typedef,并迁移到适当的类的原因。 - xtofl
显示剩余4条评论

2
我认为对std::string进行typedef是合理的。尽管如此,您仍然受到接口的约束。如果您切换到具有不兼容接口的字符串实现,可以将typedef的值更改为某个适配器类。在C++中,您可以以最小或无开销的方式执行此操作。然后,切换到新的字符串类型意味着更改适配器类。如果您发现自己经常更改适配器,则可以将其设置为模板。
但是,您仍然不能免疫他人(或将来的自己)忘记typedef并直接使用std::string的情况。

1

如果您预计字符串将来需要更改,最好的做法是将其与代码的其余部分分离。

typedef或专用类都可以实现此目的。

使用typedef是一个很好的开始:代码依赖于抽象。问题在于:客户端代码可以使用任何std::string提供的内容,因此如果您想以后迁移,您将不得不事后分析需要哪些方面(如果您不想模仿整个std::string)。

如果您想控制客户端代码可以使用的内容,最好使用具有更受限界面的适当类。

所以:了解您的需求并做出决策。


0
我会创建一个类,其中包含一个std::string作为私有成员。然后,您需要重新实现要使用的方法,但如果将来切换字符串类型,您只需要重写此类即可。
typedef在从字符串到wstring进行切换时可以正常工作,但是切换到具有不同接口的字符串类(例如qstring)将不太容易。

0
只要你将来用来替换std::string的东西具有与std::string相同的方法、构造函数等,这个方法就可以工作。例如,如果你使用std::wstring,这个方法就不适用,因为它的方法是针对宽字符而不是char的。
如果你真的计划在将来更换类型,最好的做法可能是将数据封装在一个自定义类中,并提供所需的接口,然后在保持接口不变的同时更改实现。对于你的应用程序来说,std::string可能太“原始”了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接