基于C ++策略的设计

时间:2015-11-18 17:44:27

标签: c++ string templates stdstring policy-based-design

在Alexandrescu 基于策略的设计中我不理解的是创建了没有任何共同点的新类型,在我看来,仍然存在许多应该以某种方式表示的共同点。

例如,std::stringstd::basic_string<>:allocator是非常内部的东西,在我看来,使用该类的代码不会知道该类正在使用哪个分配器。

但是因为创建了一个新类型,让我们说std::basic_string_1,所有传递std::string&的方法基本上都被破坏了,我看不到具有不同分配器的std::basic_string<>被认为与具有另一个分配器的std::basic_string<>完全不同的正当理由。

我的问题是:为什么每个std::basic_string<>都没有共同的父母,所以可以避免这个问题?通常在我的代码中,当我有Whatever<T>时,我会从某种类型的WhateverBase继承,当T没有显示在该类的公共接口上时,它可以很好地工作...

1 个答案:

答案 0 :(得分:6)

  

allocator是非常内部的东西,在我看来,使用该类的代码不应该知道该类正在使用哪个分配器。

这就是为什么通常你不在乎,只需使用std::string。大多数代码都不使用自定义分配器,因此它不是问题。

正如Kerrek SB在评论中指出的那样,您可以选择使用类型擦除分配器的std::experimental::pmr::string,因此隐藏了使用何种分配器的详细信息。这有一些运行时成本,但也有一些优势。

更一般地说,基于策略的设计导致不同类型的无法互操作的爆炸是正确的。有时这是一个问题(有时它不是)。处理这种情况的一种方法是编写通用代码,它不关心它是否涉及policy_base_ptr<X, Y, Z>policy_based_ptr<A, B, C>。编写使用“某种智能指针”的通用代码,而不关心确切的类型。但这并不总是一种选择,例如在定义接口时,您经常需要使用具体类型。

  

我的问题是:为什么每个std::basic_string<>都没有共同的父母,所以可以避免这个问题?通常在我的代码中,当我有Whatever<T>时,我会从某种类型的WhateverBase继承,当T没有显示在该类的公共接口上时,它可以很好地工作...

这意味着您的类是多态的,只知道基类的代码必须通过引用传递它。它不能通过值传递,因为它将被切片。这意味着您必须小心对象所有权,并关注引用何时仍然有效,以及谁负责销毁派生类型。

这是您在自己的软件中制作的完美合理选择,但不适合像std::string这样的通用词汇类型。必须能够按值传递字符串并轻松复制。