基于 C++ 策略的设计
C++ Policy Based Design
我在 Alexandrescu 基于策略的设计 中不理解的是创建没有任何共同点的新类型,在我看来,仍然有很多共同点应该以某种方式表示。
例如,std::string
和 std::basic_string<>
:分配器是非常内部的东西,在我看来,使用 class 的代码不应知道哪个分配器 class 正在使用。
但是由于创建了一个新类型,假设 std::basic_string_1
,所有那些传递 std::string&
的方法基本上都被破坏了,我看不出一个有效的理由具有不同分配器的 std::basic_string<>
应被视为与具有另一个分配器的 std::basic_string<>
完全不同。
我的问题是:为什么不是每个std::basic_string<>
都有共同的父节点,这样就可以避免这个问题?通常在我的代码中,当我有一个 Whatever<T>
时,我让它继承自某种 WhateverBase
,并且当 T
没有显示在那个 public 界面上时=30=],效果很好...
allocator are something very internal and, in my opinion, the code using that class shall not be aware of which allocator that class is using.
这就是为什么通常您不关心,只使用 std::string
的原因。大多数代码不使用自定义分配器,所以这根本不是问题。
正如 Kerrek SB 在评论中指出的那样,您可以选择使用 std::experimental::pmr::string
,它使用类型擦除的分配器,因此隐藏了使用哪种类型的分配器的详细信息。这有一些 运行 时间成本,但也有一些优势。
更一般地说,您是对的,基于策略的设计会导致无法互操作的不同类型的激增。有时这是一个问题(有时不是)。处理该问题的一种方法是编写不关心处理 policy_base_ptr<X, Y, Z>
还是 policy_based_ptr<A, B, C>
的通用代码。编写使用 "some kind of smart pointer" 的通用代码,您不关心确切的类型。但这并不总是一个选项,例如在定义接口时,您经常需要使用具体类型。
My question is: why there is not common parent for every std::basic_string<>
, so that this problem could be avoided? Generally in my code when I have a Whatever<T>
, I make it inherits from a WhateverBase
of some sort, and when T
is not shown on the public interface of that class, it works greatfully...
这意味着您的 class 是多态的,只知道基础 class 的代码必须通过引用传递它。它不能按值传递,因为它会被切片。这意味着您必须小心对象所有权,并关心引用何时仍然有效,以及谁负责销毁派生类型。
这是您在自己的软件中做出的完全合理的选择,但不适合像 std::string
这样的通用词汇类型。字符串可以按值传递并轻松复制是必不可少的。
我在 Alexandrescu 基于策略的设计 中不理解的是创建没有任何共同点的新类型,在我看来,仍然有很多共同点应该以某种方式表示。
例如,std::string
和 std::basic_string<>
:分配器是非常内部的东西,在我看来,使用 class 的代码不应知道哪个分配器 class 正在使用。
但是由于创建了一个新类型,假设 std::basic_string_1
,所有那些传递 std::string&
的方法基本上都被破坏了,我看不出一个有效的理由具有不同分配器的 std::basic_string<>
应被视为与具有另一个分配器的 std::basic_string<>
完全不同。
我的问题是:为什么不是每个std::basic_string<>
都有共同的父节点,这样就可以避免这个问题?通常在我的代码中,当我有一个 Whatever<T>
时,我让它继承自某种 WhateverBase
,并且当 T
没有显示在那个 public 界面上时=30=],效果很好...
allocator are something very internal and, in my opinion, the code using that class shall not be aware of which allocator that class is using.
这就是为什么通常您不关心,只使用 std::string
的原因。大多数代码不使用自定义分配器,所以这根本不是问题。
正如 Kerrek SB 在评论中指出的那样,您可以选择使用 std::experimental::pmr::string
,它使用类型擦除的分配器,因此隐藏了使用哪种类型的分配器的详细信息。这有一些 运行 时间成本,但也有一些优势。
更一般地说,您是对的,基于策略的设计会导致无法互操作的不同类型的激增。有时这是一个问题(有时不是)。处理该问题的一种方法是编写不关心处理 policy_base_ptr<X, Y, Z>
还是 policy_based_ptr<A, B, C>
的通用代码。编写使用 "some kind of smart pointer" 的通用代码,您不关心确切的类型。但这并不总是一个选项,例如在定义接口时,您经常需要使用具体类型。
My question is: why there is not common parent for every
std::basic_string<>
, so that this problem could be avoided? Generally in my code when I have aWhatever<T>
, I make it inherits from aWhateverBase
of some sort, and whenT
is not shown on the public interface of that class, it works greatfully...
这意味着您的 class 是多态的,只知道基础 class 的代码必须通过引用传递它。它不能按值传递,因为它会被切片。这意味着您必须小心对象所有权,并关心引用何时仍然有效,以及谁负责销毁派生类型。
这是您在自己的软件中做出的完全合理的选择,但不适合像 std::string
这样的通用词汇类型。字符串可以按值传递并轻松复制是必不可少的。