我正在寻找有关指针取消引用运算符 ->
的一些帮助。让我来描述我想要做的事情。
我正在为一个特殊的容器实现一个单向迭代器。容器是特殊的,因为它不会为包含的值物理分配任何空间,而是在运行时根据需要生成它们。例如,考虑容器是“ N连续的M个连续整数倍”
。由于我不希望将值直接存储在迭代器中,因此我会根据需要在堆上创建一个值。
当我需要一个指向值的指针时,如果它已过时并删除了旧指针,则会删除旧指针。这意味着, operator *()
或 operator ->()
的调用可能delete
为旧值,new
为新值,如果在最后一次调用迭代器之前,它已经使用operator ++()
进行了推进。
现在我想使用 smart_ptr
指向我的值,而不是保留原生指针。为了做到这一点,我意识到我需要更好地理解 ->
运算符的语义。
->
一元运营商?i->member
如何运作。这将转换为(pointer returned)member
,这不是语法上有效的形式。->()
闻起来更像是执行(*pointer returned).member
的二元运算符。由于“member”不是值,因此这种语义也不等同于二元运算符。->()
返回的指针会发生什么变化?谁应该拥有它?--
运算符,因此我不需要保留以前的值感谢您的回复。结束元问题,这应该是一个维基吗?
答案 0 :(得分:2)
这是回答你的问题的答案,尽管我认为它们并不像你希望的那样有用:
member
是什么。如果member
不是类/结构的字段/成员,而是指向operator ->
的返回,那么编译器会抱怨。member
确实可以是数据成员或成员函数。member
没有任何作用。它只是为了实现智能指针。说return_type *ptr = smarptr.operator ->()
。operator ->
除了实现智能指针之外的任何其他内容,我无意帮助您编写程序员编写代码后,您将辱骂和取笑。我怀疑你想要指出自己的价值。在我看来,你可以将它作为迭代器的成员值保存它,我将举例说明它如何在下面工作。但是,如果您设置使用指向您的值的指针,并且想要使用智能指针,则只需为您自己的smartptr.operator ->()
返回operator ->()
的结果。您也可以使用智能指针的成员函数(通常为get
),它返回一个“裸”指针,这可能会让人感到困惑。
以下是示例容器应如何工作的示例:
class multiples {
public:
multiples(int n, int starting_multiplier, int ending_multiplier)
: n_(n), starting_(starting_multiplier), ending_(ending_multiplier)
{
}
class const_iterator {
friend class multiples;
public:
const int &operator *() const { return curval_; }
const int *operator ->() const { return &curval_; }
const const_iterator &operator ++() { curval_ += n_; return *this; }
const const_iterator operator ++(int) {
const_iterator tmp(*this);
curval += n_;
return tmp;
}
bool operator ==(const const_iterator &b) const { return curval_ == b.curval_; }
bool operator !=(const const_iterator &b) const { return curval_ != b.curval_; }
protected:
explicit const_iterator(int n, int starting) : n_(n), curval_(starting * n) {}
private:
const int n_;
int curval_;
};
const_iterator begin() const { return const_iterator(n_, starting_); }
const_iterator end() const { return const_iterator(n_, ending_); }
private:
const int n_, starting_, ending_;
};
答案 1 :(得分:2)
您可能不需要“在堆上创建值”。至少对于数字,只需让迭代器直接包含迭代状态。
答案 2 :(得分:0)
其中很多都是由其他人回答的。我还是想分享一下 - >运算符重载工作。
当我们执行pA->Function()
时,会发生类似这样的事情(pA.operator->())->Function()
在RAII框架中,指针类需要表现得好像它是一个实际的指针。因此,需要重载箭头->
运算符。
e.g。重载 - > RAII中的运营商。
T* operator->()
{
return m_ptr;
}