C++ 这个运算符重载函数返回什么?
我从一个页面上看到以下列表:C++ 这个运算符重载函数返回什么?,c++,reference,operator-overloading,square-bracket,C++,Reference,Operator Overloading,Square Bracket,我从一个页面上看到以下列表: #include "vector.h" // An axis-aligned bounding box class AABB { public: VECTOR P; //position VECTOR E; //x,y,z extents AABB( const VECTOR& p, const VECTOR& e): P(p) ,E(e) {} // ... const SCALAR min( l
#include "vector.h"
// An axis-aligned bounding box
class AABB
{
public:
VECTOR P; //position
VECTOR E; //x,y,z extents
AABB( const VECTOR& p, const VECTOR& e): P(p) ,E(e) {}
// ...
const SCALAR min( long i ) const
{
return ((AABB*)this)->P[i] - ((AABB*)this)->E[i];
}
// ...
};
现在我不明白的是,min()用一个长值访问什么。
我查看了vector.h
,发现方括号运算符重载:
class VECTOR
{
public:
SCALAR x,y,z; //x,y,z coordinates
//...
//index a component
//NOTE: returning a reference allows
//you to assign the indexed element
SCALAR& operator [] ( const long i )
{
return *((&x) + i);
}
//...
};
后来它被用作:
// each axis
for( long i=0 ; i<3 ; i++ )
{
if( A.max(i)<B.min(i) && v[i]<0 )
{
//每个轴
对于(长i=0;i它不是递增的
&x //<- address of member x
(&x) + i //<- address of member x shifted right by i SCALAR's
*((&x) + i) // the scalar value at that point
&x/这是指针算法
在向量
结构中,标量
成员将很可能(不保证)连续出现在内存中,该代码的作者利用了这一点,只需将索引添加到结构中第一个成员的内存地址(x
)
这是输入映射到输出的方式:
0
..*(&x+0)
..x
1
..*(&x+1)
..y
2
..*(&x+2)
..z
然而,这是作者的一个相当不安全的假设:V.
(填充字节、成员顺序等…)这称为指针算术
在代码中,&x
获取x
的地址,这是一个指针;向其中添加i
意味着指针将递增sizeof(x)*i
。通常这样做是为了达到与索引到数组中相同的效果。例如,如果
int arr[10];
然后通过写入&arr[0]+i
可以有效地索引到数组中的i
th整数。在某些情况下,可能存在其他类型的连续内存块,而不是标准数组
这与所讨论的情况不完全相同,因为这里没有数组或其他类似的内存块。相反,代码假定编译器将计算VECTOR
的内存布局,这样x
、y
和z
将被放置在内存中,模拟数组布局
但是,这种做法调用C++标准的未定义行为,所以向量的实现是有缺陷的,不应该使用。
< P>在Talm []/Cudio中所做的操作是“指针算术”——在这里使用正常算术运算符(<代码> +/COD>)使用指针导航内存(通常使用数组)
您可以在此处看到更多此技术的示例:
需要注意的是,如果SCALAR
是某种非数组类型,那么我认为给出的代码是“危险的”,假定代码“> x< /代码>,<>代码> y>代码>代码> z代码>代码,将在相邻的内存位置,这不是标准C++所保证的。如果你试图在一个不能保证这个假设的平台上使用这个代码,结果就是<代码>操作符[]。
充其量会返回一些未定义的值,或者在最坏的情况下会导致分段错误。(AABB*)这
?(&x)+i
?什么…从这段代码中跑掉了。是的,我的反应是一样的:)这段代码(这是一个错误操作的好例子)正在努力访问标量值(即x,y,z)作为一个数组。特别是,运算符[](const long i)
使用x的地址(&x
)以及索引(i
)来查找相应元素的内存地址,并返回其值。此代码产生未定义的行为,填充可能导致字段值之间出现漏洞。不要这样做,也不要对编写它的程序员大喊大叫。可能是我,但我不明白你的问题是什么。为什么x
参考增加了i
?因为i
用于选择要返回的x
、y
或z
。这是你的问题吗?@GManNickG:即使有保证,也会是UB,因为技术索引超出了范围,对吗?需要补充的是:这种行为未定义的原因是编译器有时会更改间距,甚至顺序,在数据段中设置变量以提高性能-这称为内存对齐。特别是在地址空间不同的机器上,它会发生变化。@Jon:是的,说得好。我们只保证&x<&y<&z
(在代码< > Tayl Roalees:实际上在代码>结构> /CODE中,它只是C++中代码< >类< />的别名,保证成员的顺序遵循声明的顺序。当创建C时,通常将结构直接写入文件或网络,这样就不希望优化器移动成员。nx,很高兴知道。填充是否也一样?是否没有带结构的填充?
?这是1999年10月18日的一篇文章:)解释了这一点。我怀疑这段代码相当古老:PThanks。你是第一个,这是你的绿色徽章