基于C++策略的设计



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

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

但是,由于创建了一个新的类型,比如std::basic_string_1,所有传递std::string&的方法基本上都被破坏了,我看不出有什么合理的理由可以解释为什么具有不同分配器的std::basic_string<>与具有另一个分配器的std::basic_string<>完全不同。

我的问题是:为什么每个std::basic_string<>都没有一个共同的父级,这样就可以避免这个问题?一般来说,在我的代码中,当我有一个Whatever<T>时,我会让它继承自某种类型的WhateverBase,当T没有显示在该类的公共接口上时,它可以很好地工作。。。

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

这就是为什么你通常不在乎,只使用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这样的通用词汇类型。至关重要的是,字符串可以按值传递并轻松复制。

相关内容

  • 没有找到相关文章

最新更新