C++ c++;()算子问题

C++ c++;()算子问题,c++,operator-overloading,C++,Operator Overloading,在尝试重载()运算符以访问阵列时,我遇到了另一个问题: const OctTreeNode*& operator()(const int i, const int j, const int k) const{ return m_cells[k*m_resSqr+j*m_res+i]; } OctTreeNode*& operator()(const int i, const int j, const int k){ return m_cells[k*m_re

在尝试重载()运算符以访问阵列时,我遇到了另一个问题:

const OctTreeNode*& operator()(const int i, const int j, const int k) const{ 
    return m_cells[k*m_resSqr+j*m_res+i];
}

OctTreeNode*& operator()(const int i, const int j, const int k){ 
    return m_cells[k*m_resSqr+j*m_res+i];       
}

vector<OctTreeNode*> m_cells;

怎么回事?我宣布它完全像在另一个类。唯一的区别是另一个类是泛型的,在这里我使用T&而不是OctreeNode*&

第一个操作符应该返回const

const OctTreeNode * const & operator()(const int i, const int j, const int k) const{ 
        return m_cells[k*m_resSqr+j*m_res+i];
}
。。。或者是
*
之前的常量,我似乎永远也记不起来了-_-

第一个常量告诉我们不能修改OctTreeNode,第二个常量告诉我们不能修改指向它的指针(例如将其设置为NULL),而第三个常量告诉我们该方法不会更改对象


老实说,我不确定是否需要第一个,因为我们需要为方法授予常量正确性的唯一一件事是,没有人会更改对这些指针的引用。

传递常量值没有什么意义,就像你对I,j,k所做的那样。

常量运算符不正确,您正在返回指向常量OctTreeNode的指针的非常量引用

也就是说,如果将指针声明为

const int *a;
a
不是常数,
a
指向的是常数。因此,当您将返回类型声明为

const OctTreeNode*&
OctTreeNode是常量,但指针不是。这是一个错误,因为您的成员函数是const,因此std::vector是const,因此它返回的指针也是常量-最终您尝试将const指针作为非const指针返回

要更正此问题,请删除引用

const OctTreeNode* operator()

因为返回对常量指针的引用没有多大意义,所以您不能修改指针,而且引用(可能)无论如何都会与指针大小相同。

Kornel是正确的。为了澄清常量是在*之前还是之后,请在。两种类型
const-OctTreeNode*const&
OctTreeNode-const*const&
是相同的,从右到左读取时很容易理解

const-OctTreeNode*const&
是对指向const的OctTreeNode的常量点的引用

OctTreeNode const*const&
是对指向常量OctTreeNode的常量指针的引用

请注意,这些类型不同于无效类型
const OctTreeNode const*&
。这将是对指向常量OctTreeNode(即常量)的指针的引用


注意句子的最后一部分,const OctTreeNode是const。其中一个常量是冗余的,如果它是合法的,那么这种类型将相当于
const-const-OctTreeNode*&

thx。但是你能解释一下为什么吗?那么为什么第一个操作符返回Fred&而不是Fred?一个表达式中的三个常量让我对这些常量实际上是什么感到困惑mean@genesys,函数为
const
,因此它意味着您返回的引用无法修改。
*
后面的
const
表示指针本身不能更改,这是constness所必需的。第一个
const
表示
OctTreeNode
本身不能更改。这个
const
实际上不是必需的,但是对于语义
const
建议使用ness。试着在注释中说出这样的事情,因为这不是真正问题的答案。对不起,还没有真正了解这个地方的窍门:)我有时会将我的值参数作为const传递。这对我有两个帮助——如果我错误地尝试并修改了一个,编译器会通知我,其次,语义现在更清晰了。唯一的缺点是函数在视觉上更大,在认知上可能需要更长的时间才能理解。@Stephen:由于const不会改变函数,只是让编译器内部检查,因此您会发现有人建议在头声明中使用非const签名(
void f(int);
)而实现中的常量签名(
void f(const int){…}
)。这将提供一个干净的API(您的用户并不真正关心您是否在内部更改复制的参数,同时允许编译器检测您谈论的错误类型。并将其更改为非常量参数(如果您希望在内部更改参数)不会更改标头。是否有理由返回指向指针的引用而不是指向元素的引用?…或指向成员的指针?返回常量引用的想法是,它可能比返回完整副本便宜得多,但如果类型是整数或指针,则没有多大意义。(假设无法将引用返回到实际对象中,这将是一种更好的方法)“返回对常量指针的引用没有多大意义”接口的一致性?如果他在一种情况下返回指针,在另一种情况下返回指针的引用,则一个版本返回左值,另一个版本返回右值。这会影响您是否可以执行
&This->operator()(1,2,3)
,并将生成的指针与另一个类似的指针进行比较。不知道这是否对提问者有用,但这是两者之间的区别。这是真的,但从我的头脑中我想不出任何地方它会有用-如果你需要记下它的地址,你可能会想更改它。好吧,你可以出于某种原因,可能需要测试对运算符()的两个调用是否访问了相同的元素(而不是仅访问包含相同值的元素)。在这种情况下,
&foo(a,b,c)
=
&foo(x,y,z)
当且仅当a==x&&b==y&c==z。所以还有另一种方法,如果你传递所有三个坐标,而不仅仅是一个参考。
const OctTreeNode* operator()