【问题标题】:Incremental number using the "Curiously Recurring Template Pattern"使用“Curiously Recurring Template Pattern”的增量数
【发布时间】:2011-04-06 17:29:55
【问题描述】:

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

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

Address x;
Address y;

x.addr 应该是 1,而y.addr 应该是 2。

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

TIA, 吉尔

【问题讨论】:

    标签: c++ templates counter auto-increment crtp


    【解决方案1】:

    您在这里并不需要它,因为您不需要捕获对象的破坏。您会注意到,该 Wikipedia 页面上的示例保留了该类型存在的对象总数,因此 CRTP 有两个方便的功能:

    1. 因为它是一个基类,所以调用了它的析构函数(一个成员也可以实现这一点)。
    2. 因为它是在派生类类型上模板化的,所以从它继承的每个类都有一个单独的计数器,如果它们使用多重继承,则包括层次结构中的不同类,每个类都包含自己的 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> {
    };
    

    【讨论】:

    • +1 和get_id 甚至可以是类的私有静态函数,使其更多的实现细节。请注意,如果您在多线程环境中运行,因为显示的解决方案不是线程安全的。
    • 清晰完整的解释!谢谢你们!
    【解决方案2】:

    对于您正在尝试做的事情来说,这似乎有点矫枉过正。如果您只需要一个唯一值,请使用静态整数并在每次实例化对象时递增它。然后将每个实例(即非静态)变量设置为该值。

    【讨论】:

      【解决方案3】:

      当然,您可以完全按照您引用的 Wikipedia 文章中的说明进行操作。 (除了听起来好像您不想减少 dtor 中的计数器。)或者,如果您只需要它用于 Address 类,您可以一次性执行 CRTP 实现中的操作:

      static int n_addresses = 0;
      class Address {
        int addr;
        Address() { addr = ++n_addresses; }
      };
      

      或类似的东西。

      【讨论】:

        【解决方案4】:
        public class Address
        {
            private static int addrCounter = 1;
        
            public int addr { get; private set; }
        
            public Address()
            {
                addr = addrCounter++;
            }
        }
        

        【讨论】:

          【解决方案5】:

          您也可以使用类内部的静态计数器:

          class Address
          {
            static int s_Count; // define this variable in appropriate cpp file
            int addr;
          public:
            Address () : addr(++ s_Count) {}
          };
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-09-18
            • 2023-04-07
            • 2012-01-01
            • 2013-06-04
            • 1970-01-01
            • 2015-11-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多