I want to im开发者_JAVA技巧plement a class Address
that, when created, initializes its field addr
to a unique value. That value has to increment by one every time I create an Address
instance.
Let's make an example. After the following code has been executed:
Address x;
Address y;
x.addr
should be 1, while y.addr
should be 2.
To accomplish that, I was thinking of the Curiously Recurring Template Pattern. Would it be feasible? Also, are there simpler methods to achieve the same behavior?
TIA, Jir
You don't really need it here, because you don't need to capture destruction of the object. You'll note that the example on that Wikipedia page keeps a running total of how many objects exist of the type, so CRTP has two handy features:
- because it's a base class, its destructor is called (a member would also achieve this).
- because it's templated on the derived class type, there's a separate counter for each class that inherits from it, including different classes in a hierarchy if they use multiple inheritance to each include their own CRTP base, without writing a lot of code for each class.
If you just want a unique value for each member of a single class, then thread-safety aside you can do it like this:
int get_id() {
static int counter = 0;
return ++counter;
}
class Address {
int addr;
public:
Address() : addr(get_id()) {}
};
Following the CRTP example, you could template get_id
and use Address
as the argument if you have multiple classes to track and want them to each have their own space of IDs.
And for this use-case, if you did use CRTP you could put the data member addr
in the template base class, which is a win if you have a lot of classes, since there's less to type for each class using it:
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> {
};
That seems like overkill for what you're trying to do. If all you need is a unique value, use a static integer and increment it each time you instantiate an object. Then set a per-instance (i.e. non-static) variable to that value.
Sure, you can do it exactly as shown in the Wikipedia article you referenced. (Except that it doesn't sound as if you want to decrement the counter in the dtor.) Or, if you only need it for the Address
class, you can just do what the CRTP implementation there does as a one-off:
static int n_addresses = 0;
class Address {
int addr;
Address() { addr = ++n_addresses; }
};
or something of the kind.
public class Address
{
private static int addrCounter = 1;
public int addr { get; private set; }
public Address()
{
addr = addrCounter++;
}
}
You can use also static counter internal to class:
class Address
{
static int s_Count; // define this variable in appropriate cpp file
int addr;
public:
Address () : addr(++ s_Count) {}
};
精彩评论