templates - C++ 具有复杂构造函数的对象的通用构建器方法

标签 templates c++11 builder generic-programming

我目前正在编写一个小型通用库,用于在场景中放置对象。对象的排列应根据对象内容的边界框来决定。该类目前看起来像这样:

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/

相关文章:

flash - 在 Flash Builder 4.5 上生成 IPA 文件 (iphone)

java - Builder Factory 返回不同的子接口(interface)

android - NotificationCompat.Builder 中通知时出现 NullPointerException

c++ - GCC 看不到通过多重继承实现

java - Android主模板布局文件?

c++ - 如何从结果创建并发::任务?

c++ - 从原始指针创建 shared_ptr 的链表

Python UnicodeDecodeError : 'utf8' codec can't decode byte. ..意外的代码字节

c++ - 一个 friend 的缩写模板函数——clang和gcc的区别

c++11 - 枚举值需要多少位?