我目前正在编写一个小型通用库,用于在场景中放置对象。对象的排列应根据对象内容的边界框来决定。该类目前看起来像这样:
template<class T>
class Object {
public:
Object() = default;
Object(const T& content, const Rect& bounding_box)
: _content(content)
, _bounding_box(bounding_box) {}
private:
T _content;
Rect _bounding_box;
};
现在,要构造对象,我们需要知道边界框。当然,它取决于内容的类型 T
,并且计算起来可能相当复杂(即文本)。
我的想法是用户应该提供自己的Measurer
来为他自己的内容执行此计算。然后可以通过以下方式创建对象:
template <class T, class Measurer>
Object create_label(const T& value, Measurer op)
{
return Object(value, op(value));
}
是否应该将此方法合并到 Object
类中(类似于策略)?我在想类似于 STL 中的分配器的东西。是否有针对此类问题的通用设计模式以及如何编写这样的类?
此外,构造函数 Object(const T& content, const Rect&bounding_box)
是否应该标记为 protected
,以便用户指向 create_label
方法?
最佳答案
我想你想看看静态成员函数。这种类型的方法不需要(或拥有)要操作的对象,因此它更像是全局函数,但它具有像类方法一样的范围和可见性。
工厂方法(例如 createLabel)通常在类中声明,如下所示:
class Object {
public:
static Object createLabel(...);
}
现在因为这是一个静态方法,您可以直接调用它而无需实例:
Object O=Object.createLabel(...);
如果您想遵循此策略,那么您的构造函数应该是私有(private)的或 protected ,以阻止类用户直接实例化它们。 (顺便说一句,这对于像您这样的模板类同样有效)
您可以使用各种其他策略来解决您的特定问题,根据您的情况,这些策略可能会更方便:
- 定义一个名为 getMeasurer 的抽象方法,该方法的定义如下 对于每个对象子类 - 这似乎对测量器有更多的约束 在代码和语义上都与子类紧密相关。
- 在类/一个方法上使用部分模板规范(这是 如果您不太熟悉 C++,那么这相当技术性)
- 您可以使所有对象的构造函数的签名显式包含 测量器(而不是边界框级别)
编辑:应OP的要求,关于部分模板解决方案的一些想法: 最直接的方法是在模板定义中简单地声明一个函数,如下所示
template<class T>
class Object {
.....
private:
BoundingBox measureMe();
}
现在,由于没有为measureMe提供*definition&(上面是一个声明),任何实例化的对象实例都将导致链接器错误,因为没有定义MeasureMe()。
但是您为特定类型提供特定实现,因此您可以包含各种特定类型的定义:
BoundingBox Object<MyThing1>::measureMe()
{
... calculatethe size of a MyThing1
}
BoundingBox Object<MyThing2>::measureMe()
{
... calculate the size of a MyThing2
}
现在,如果您尝试实例化尚未为其定义度量的对象类型,您仍然会收到错误;但已知类型可以按您的意愿工作。
请记住,您仍然可以定义此函数的通用模板版本,如果没有更具体的可用版本,则将使用该版本,如果您的大多数情况使用相同的逻辑,但有一些边缘异常(exception),这可能对您有用.
关于templates - C++ 具有复杂构造函数的对象的通用构建器方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32245882/