是否可能在我的模板类中有一个静态成员变量,而类的用户不必知道它? [英] Is it possible to have a static member variable in my templated class, without the class's user having to know about it?

查看:139
本文介绍了是否可能在我的模板类中有一个静态成员变量,而类的用户不必知道它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板容器类,类似这样的玩具代码:

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

/ **引用数组中的第一个项,
*或一个默认构造的项,如果数组为空。
* /
const ItemType& GetFirstItemWithDefault()const
{
return(_numItems> 0)? _items [0]:_defaultItem;
}

[其他方法省略,因为它们不相关]

private:
int _numItems; //有多少个有效项目(_items)指向
ItemType * _items; // demand-allocated
const ItemType _defaultItem;
};

这个类非常方便使用 - 任何代码只需#includeMyVector.h然后开始声明类型MyVector和MyVector的对象等等,并且它所有的Just Works(tm)没有任何需要的周转。



有一件事,然而,是存在_defaultItem成员变量,这是唯一地给予GetFirstItemWithDefault()能力,当容器为空时返回一个有效的引用。反对的是,如果我声明N个MyVector对象,这意味着_defaultItem的N个副本也将出现在RAM中 - 即使它们都是相同的和只读的,所以真的只需要其中一个进程,而不是一个MyVector。



所以,显而易见的解决方案是使_defaultItem静态....但AFAICT附带成本:如果我这样做,不再可能的任何旧的代码只是简单地#includeMyVector.h和去...现在用户必须肯定声明一个静态变量的存储在他的.cpp文件,它是(a )在屁股的痛苦,和(b)意味着代码的用户必须知道类的内部实现的细节。因为_defaultItem是一个私有成员变量,类的用户不应该考虑它,甚至意识到它存在,更不用说知道他需要为它声明存储。 (如果两个单独的代码片段都声明了它的存储,每个不知道另一个做了相同的事情,这不会导致重复符号链接器错误?)



因此,我的问题是:有没有办法告诉C ++为这个静态成员变量自动提供一个唯一的存储(每个实例化类型的MyVector),以便MyVector的用户不必知道它? (注意,对于MyVector< ...>的所有可能的实例化,它将需要是自动的,而不仅仅是对于一些常见的情况)

解决方案< >

如果它是一个模板,编译器将为你做魔法。只要将静态成员放在标题中,编译器就会看到它只是实例化一次。

  template< class ItemType> 
class MyVector
{
public:
// ...
private:
static const ItemType _defaultItem;
};


模板< class ItemType>
const ItemType MyVector< ItemType> :: _ defaultItem;


I have a templated container class, something like this toy code:

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;
};

This class is really convenient to use -- any code can just #include "MyVector.h" and then start declaring objects of type MyVector and MyVector and so on, and it all Just Works (tm) without any futzing around required.

One thing that kind of bothers me, however, is the presence of the _defaultItem member variable, which is there solely to give GetFirstItemWithDefault() the ability to return a valid reference when the container is empty. The objection is that if I declare N MyVector objects, that means N copies of _defaultItem will be present in RAM as well --- even though they are all identical and read-only, and so there really only needs to be one of them per process, not one per MyVector.

So, the obvious solution is to make _defaultItem static .... but AFAICT that comes with a cost: if I do that, it is no longer possible for any old piece of code to simply #include "MyVector.h" and go... now the user has to be sure to declare storage for that static variable in one of his .cpp files, which is (a) a pain in the butt, and (b) means that the user of the code has to be aware of the details of the internal implementation of the class. Since _defaultItem is a private member variable, the user of the class shouldn't have to think about it or even realize it exists, let alone know that he needs to declare storage for it. (and what if two separate pieces of code both declare storage for it, each not knowing the other has done the same thing? Wouldn't that cause a duplicate-symbol linker error?)

Therefore, my question is: is there any way to tell C++ to automatically provide one unique storage (per instantiated type of MyVector) for this static member variable, so that users of MyVector don't have to know about it? (Note that it would need to be automatic for all possible instantiations of MyVector<...>, not just for a few common cases)

解决方案

If it is a template, the compiler will do the magic for you. Just put the static member in the header, and the compiler will see to that it is just instantiated once.

template <class ItemType> 
class MyVector
{
public:
    //...
private:
    static const ItemType _defaultItem;
}; 


template <class ItemType> 
const ItemType MyVector<ItemType>::_defaultItem;

这篇关于是否可能在我的模板类中有一个静态成员变量,而类的用户不必知道它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆