我有一个模板化的容器类,类似于这个玩具代码:
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; };
这个类非常方便使用 – 任何代码都可以#include“MyVector.h”然后开始声明MyVector和MyVector类型的对象,等等,而且所有Just Works(tm)都没有任何需要的东西.
然而,令我困扰的一件事是_defaultItem成员变量的存在,这仅仅是为了让GetFirstItemWithDefault()能够在容器为空时返回有效的引用.反对意见是,如果我声明N MyVector对象,那意味着_defaultItem的N个副本也将出现在RAM中 – 即使它们都是相同且只读的,因此实际上只需要其中一个过程,而不是每个MyVector一个.
因此,显而易见的解决方案是使_defaultItem成为静态….但AFAICT带来了成本:如果我这样做,任何旧的代码片段都不再可能简单地#include“MyVector.h”而去. ..现在用户必须确保在他的一个.cpp文件中为该静态变量声明存储,这是(a)屁股的痛苦,并且(b)意味着代码的用户必须知道该类的内部实现的细节.由于_defaultItem是一个私有成员变量,因此该类的用户不必考虑它或甚至意识到它存在,更不用说知道他需要为它声明存储. (如果两个独立的代码段都为它声明了存储,每个不知道另一个已经做了同样的事情怎么办?这不会导致重复符号链接器错误吗?)
因此,我的问题是:有没有办法告诉C自动为这个静态成员变量提供一个唯一的存储(每个实例化类型的MyVector),以便MyVector的用户不必知道它? (请注意,对于MyVector< ...>的所有可能实例化,它都需要是自动的,而不仅仅是针对一些常见情况)
解决方法
如果它是一个模板,编译器将为你做神奇的事.只需将静态成员放在头文件中,编译器就会看到它只是实例化了一次.
template <class ItemType> class MyVector { public: //... private: static const ItemType _defaultItem; }; template <class ItemType> const ItemType MyVector<ItemType>::_defaultItem;