Возможно ли иметь статическую переменную-член в моем шаблонном классе без необходимости знать об этом пользователю класса?

У меня есть шаблонный класс контейнера, что-то вроде этого игрушечного кода:

template <class ItemType> class MyVector
{
public:
   MyVector() : _numItems(0), _items(NULL) {/* empty */}

   /** Returns a reference to the first item in our array,
     * or a default-constructed item if the array is empty.
     */
   const ItemType & GetFirstItemWithDefault() const
   {
      return (_numItems > 0) ? _items[0] : _defaultItem;
   }

   [other methods omitted because they aren't relevant]

private:
   int _numItems;       // how many valid items (_items) points to
   ItemType * _items;   // demand-allocated
   const ItemType _defaultItem;
};

Это class действительно удобен в использовании - любой код может просто #include "MyVector.h", а затем начать объявлять объекты типа MyVector, MyVector и так далее, и все это просто работает (tm) без каких-либо дополнительных действий.

Одна вещь, которая меня беспокоит, - это наличие переменной-члена _defaultItem, которая предназначена исключительно для того, чтобы дать GetFirstItemWithDefault () возможность возвращать действительную ссылку, когда контейнер пуст. Возражение состоит в том, что если я объявляю N объектов MyVector, это означает, что N копий _defaultItem также будут присутствовать в ОЗУ - даже если все они идентичны и предназначены только для чтения, поэтому на самом деле должен быть только один из них на каждый процесс, а не один на MyVector.

Итак, очевидное решение - сделать _defaultItem статическим ... но AFAICT, за который приходится платить: если я это сделаю, ни один старый фрагмент кода больше не сможет просто #include "MyVector.h" и вперед ... теперь пользователь должен обязательно объявить хранилище для этой статической переменной в одном из своих файлов .cpp, что (а) является головной болью и (б) означает что пользователь кода должен знать детали внутренней реализации класса. Поскольку _defaultItem является частной переменной-членом, пользователю класса не нужно думать об этом или даже осознавать, что он существует, не говоря уже о том, что ему нужно объявить хранилище для него. (и что, если два отдельных фрагмента кода объявляют хранилище для него, каждый из которых не знает, что другой сделал то же самое? Разве это не вызовет ошибку компоновщика с повторяющимися символами?)

Поэтому мой вопрос: существует ли каким-либо способом указать C ++ для автоматического предоставления одного уникального хранилища (для каждого экземпляра типа MyVector) для этой статической переменной-члена, чтобы пользователи MyVector не знали об этом? (Обратите внимание, что это должно быть автоматическим для всех возможных экземпляров MyVector <...>, а не только для нескольких общих случаев)

7
задан Jeremy Friesner 17 June 2011 в 16:39
поделиться