我正在学习内存管理并使用结构在堆中手工制作堆栈。该部分有效,但后来我决定也尝试学习运算符重载,并决定尝试使用 [] 运算符使所有元素可访问(我知道在 O(n) 时间内)。然而,由于某种原因,虽然 stack->operator 或多或少正常工作,但 i 不为 0 的 stack[i] 给出了一个看似随机的数字。这是代码:
#include <iostream>
struct stackElem
{
int v;
stackElem *p;
stackElem(){
v = 0;
p = nullptr;
}
~stackElem(){
delete p;
p = nullptr;
}
int& operator[](size_t index) {
if(index == 0) return this->v;
stackElem *temp = this->p;
for (size_t i = 0; i < index; i++){
temp = temp->p;
}
return temp->v;
} //stack[0] returns top, then goes down
const int operator[](size_t index) const {
if(index == 0) return this->v;
stackElem *temp = this->p;
for (size_t i = 0; i < index; i++){
temp = temp->p;
}
return temp->v;
}
};
void stackPush(stackElem *&top, int val){
stackElem *temp = top;
top = new stackElem;
top->v = val;
top->p = temp;
} //First in, last out
int stackPop(stackElem *&top){
int ret = top->v;
stackElem *temp = top->p;
top->p = nullptr;
delete top;
top = temp;
return ret;
}
int main(){
stackElem *list = new stackElem;
stackPush(list, 13);
stackPush(list, 14);
stackPush(list, 15);
stackPush(list, 16);
stackPush(list, 17);
stackPush(list, 18);
std::cout<<list->p->v<<std::endl;
std::cout<<list[0].v<<"\t"<<list[1].v<<std::endl;//<<list[2].v<<list[3].v<<list[4].v<<list[5].v;
list->operator[](1) = 100; //This works correctly
int test = list->operator[](1); //This works correctly
int test2 = list[1]; //This breaks
std::cout<<test<<std::endl;
std::cout<<list[1]; //This breaks
return 0;
}
如您所见,我有 2 个重载(对于 int = stack[] 和 stack[] = int,正如我在其他地方看到的那样)。返回 consts 的那个不允许 stackElem *temp = this 因为“你不能用 const stackElem * 初始化 stackElem *”,这就是为什么我使用有趣的 if(index == 0) 并将 temp 分配给 this->p 。
在
int test2 = list[1];
中,下标运算符是指针的内置下标运算符,即给定指针 stackElem*
和偏移量 int
,它会产生 stackElem
,即从开始处的偏移量。这与数组的下标运算符完全相同。
要调用您自己的重载
operator[]
,您必须首先取消引用指针:
(*list)[1] // or
list[0][1]