1

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

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

Address x;
Address y;

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

为了实现这一点,我想到了奇怪重复的模板模式。是否可行?此外,是否有更简单的方法来实现相同的行为?

蒂亚,吉尔

4

5 回答 5

7

您在这里并不需要它,因为您不需要捕获对象的破坏。您会注意到,该 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> {
};
于 2011-04-06T17:33:00.460 回答
1

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

于 2011-04-06T17:33:47.573 回答
0

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

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

或类似的东西。

于 2011-04-06T17:35:11.490 回答
0
public class Address
{
    private static int addrCounter = 1;

    public int addr { get; private set; }

    public Address()
    {
        addr = addrCounter++;
    }
}
于 2011-04-06T17:35:57.113 回答
0

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

class Address
{
  static int s_Count; // define this variable in appropriate cpp file
  int addr;
public:
  Address () : addr(++ s_Count) {}
};
于 2011-04-07T03:36:13.640 回答