c++ - 运算符 [] 无法与手工制作的结构堆栈正常工作?

问题描述 投票:0回答:1

我正在学习内存管理并使用结构在堆中手工制作堆栈。该部分有效,但后来我决定也尝试学习运算符重载,并决定尝试使用 [] 运算符使所有元素可访问(我知道在 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 。

c++ struct stack operator-overloading
1个回答
0
投票

int test2 = list[1];
中,下标运算符是指针的内置下标运算符,即给定指针
stackElem*
和偏移量
int
,它会产生
stackElem
,即从开始处的偏移量。这与数组的下标运算符完全相同。

要调用您自己的重载

operator[]
,您必须首先取消引用指针:

(*list)[1] // or
list[0][1]
© www.soinside.com 2019 - 2024. All rights reserved.