我写了一个小的“懒载体”类(或,延迟矢量),其应该看起来像任何地方使用std::vector一个std::vector和使用,但它加载它的元素“懒惰”,即它会加载元件n(并且可能是从磁盘几),只要有人访问元素n。 (其原因在于,在我的应用程序,而不是所有的元素装入内存。)

下面是本LazyVector类,但存在与使用这样的矢量const成员函数的问题,见下文。

template<class T>
class LazyVector {
  std::vector<T> elems_;
  void fetchElem(unsigned n){
    // load the n-th elem from disk into elems_ etc
  }
public:
  const T& operator[](unsigned n) const {
    fetchElem(n); // ERROR: ... discards qualifiers       
    return elems_[n];
  }
  T& operator[](unsigned n) {
    fetchElem(n);
    return elems_[n];
  }
  // and provide some other std::vector functions
};

正如我所说的,存在一个问题,当一个const成员函数询问的LazyVector的元件。由LazyVector的性质,访问一个元素是 const,即,它会改变下面的矢量vec,这在该上下文中禁止的。该foo成员函数必须const并且不能更改。我该如何解决这个问题?

class Foo {
  LazyVector<const std::string*> vec;
  void fct(int n) const { // fct must be const 
    const std::string* str = vec[n];
    // do something with str 
  }
};
有帮助吗?

解决方案

您可以使用可变数据成员或const_cast会在你LazyVector类的实现。因此,你可以创建你的消费类所需要的常量性的假象,而无需实际是常量。

其他提示

在使用可变关键字所述elems_数据成员。

在常量操作者用于显示该对象在逻辑上是常量。结果 您的数据在磁盘上的事实是不伦不类的对象不改变状态,因此您可以委托工作,为数据实际持有到另一个对象缓存(其中存储的数据是一个实现细节,而不是部分对象状态)。

class LazyVector
{
    public:
        int const& operator[](int index) const
        { 
            data->fetchElement(index);
            return data->get(index);
        }
    private:
        std::auto_ptr<LazyDataCache>   data;
};

下面数据是一个指针(智能指针但仍然是一个指针)。只要指针不会改变你不改变LazyVector成本的烦躁。但仍可以调用非const的方法上的对象指向由数据(记住它是该指针是常量不是对象指向)。

有关这样的事情,在mutable关键字是。把你的缓存为可变对象到类。那是因为你的缓存似乎无法改变你的对象的逻辑内容/状态(你的载体的即元素或它的大小不会改变)。

const方法并不说明他们没有实际改变你的对象。他们指出,他们不会改变你的对象的抽象价值。被抽象化了的实施细则仍可能通过const函数来改变。

在可变为这种例。让你的矢量可变或添加包含某种缓存条目的可变缓存成员。

读取什么的语义一个const成员函数通过安东尼威廉姆斯回答。

声明elems_作为mutable

mutable std::vector<T> elems_;

还有其他的东西可以做,但是这是做它的支持方式。

编辑:这样做的另一种方法是添加另一部件,并将其设置在构造:

std::vector<T> *mutable_elems_;

mutable_elems_(&elems_)

这样做的一个粗的方法是

LazyVector* p = const_cast<LazyVector*>(this);
p->fetch();

我想会有这样做的更好的方法。但是,这会工作。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top