我想实现一个class Address,该代码在创建时会将其字段addr初始化为唯一值。每当我创建Address实例时,该值必须增加一。

让我们举个例子。执行以下代码后:

Address x;
Address y;
x.addr应该为1,而y.addr应该为2。

为此,我想到了Curiously Recurring Template Pattern。可行吗?
另外,是否有更简单的方法来实现相同的行为?

TIA,
吉尔

最佳答案

您实际上并不需要它,因为您无需捕获对象的破坏。您会注意到,该Wikipedia页面上的示例始终运行着该类型存在的对象总数,因此CRTP具有两个方便的功能:

  • 因为它是基类,所以调用了它的析构函数(成员也可以实现此目的)。
  • ,因为它是基于派生类类型的模板,所以每个类都有一个单独的计数器来继承它,如果它们使用多重继承来包含自己的CRTP基础,则在层次结构中包括不同的类,而无需为每个类编写大量代码。

  • 如果您只想为单个类的每个成员提供唯一的值,那么除了线程安全性之外,您还可以这样:
    int get_id() {
        static int counter = 0;
        return ++counter;
    }
    
    class Address {
        int addr;
      public:
        Address() : addr(get_id()) {}
    };
    

    在CRTP示例之后,如果您要跟踪多个类并希望它们每个都有自己的ID空间,则可以模板化get_id并使用Address作为参数。

    在这个用例中,如果您确实使用了CRTP,则可以将数据成员addr放在模板基类中,如果您有很多类,这是一个胜利,因为使用它的每个类键入的内容更少:
    template <typename Derived>
    class unique_addr {
      protected:
        int addr;
        unique_addr() : addr(get_id<Derived>()) {}
    };
    
    class Address : public unique_addr<Address> {
    };
    
    class OtherAddress : public unique_addr<OtherAddress> {
    };
    

    10-04 14:54