c++ перегрузить оператор []

Я пытаюсь перегрузить оператор нижнего индекса [] в своем классе, который использует связанный список для создания карты. Это и несколько вариантов, таких как добавление const, - это то, что я пробовал.

заголовок

int& operator[](std::string key);

а затем определение перегрузки в отдельном файле

int& mapLL::operator[](std::string key){ 
   int val = this->get(key);
   return val;
}

это ошибка не знаю как исправить

main.cpp: In function ‘int main()’:
main.cpp:38:24: error: invalid types ‘mapLL*[const char [4]]’ for array subscript
 int a = list3["ghi"]; 
                    ^
mapLL.cpp: In member function ‘int& mapLL::operator[](std::string)’:
mapLL.cpp:110:9: warning: reference to local variable ‘val’ returned [-Wreturn-local-addr]
   int val = this->get(key);
       ^

Затем в основном файле я пытаюсь это

mapLL *list3 = new mapLL();
list3->set("abc",1);
list3->set("def",2);
list3->set("ghi",3);
list3->set("jkl",1);
list3->toString();
cout << list3->get("ghi") << endl;
int a = list3["ghi"]; 
cout << a << endl;
delete list3;

получить функцию

int mapLL::get(std::string key){
    bool found = false;
    node *me = (node *) first;
    if(is_empty()){
        return -2;
    }
    while(!found){
        if (me->getKey() == key){
            return me->getValue();
        }else{
            if (me->getNext() == 0){
                return -1;
            }else{
                me = (node *) me->getNext();
            }
        }
    }
}

person cmb    schedule 15.10.2015    source источник
comment
Похоже, что list3 - это указатель, поэтому вам нужно будет сделать (*list3)["ghi"]   -  person Brian Bi    schedule 15.10.2015
comment
Кроме того, как предупреждает компилятор, метод возвращает ссылку на временный объект. Это определенно не то, чем вы хотите заниматься.   -  person Jon    schedule 15.10.2015
comment
Есть ли причина, по которой вам нужно использовать динамическое выделение памяти (например, оператор new)? Это не Java или C#. Вы можете объявить list3 как локальную или глобальную переменную без new.   -  person Thomas Matthews    schedule 15.10.2015
comment
@ Брайан Я только что попробовал ваши предложения, и это сработало, есть ли способ переписать функцию, чтобы list3["ghi"] работало   -  person cmb    schedule 15.10.2015
comment
@cmb не объявляйте list3 указателем. Это не должно быть одним.   -  person jaggedSpire    schedule 15.10.2015
comment
@cmb Проблема не в вашей функции. Вы объявили list3 как указатель на mapLL, поэтому, естественно, вам нужно разыменовать его, чтобы получить доступ к базовому объекту. Попробуйте объявить list3 следующим образом mapLL list3; Тогда вы сможете заставить list3["ghi"] работать.   -  person Mohamad Elghawi    schedule 15.10.2015
comment
Можете ли вы опубликовать функцию get ()?   -  person Cem Kalyoncu    schedule 15.10.2015


Ответы (2)


Я рекомендую воздержаться от использования необработанных указателей и динамического размещения. Ваша проблема связана с неправильным использованием указателей.

Используйте прямые объявления:

mapLL list3;
list3.set("abc",1);
list3.set("def",2);
list3.set("ghi",3);
list3.set("jkl",1);
list3.toString();
cout << list3.get("ghi") << endl;
int a = list3["ghi"]; 
cout << a << endl;
person Thomas Matthews    schedule 15.10.2015
comment
@cmb ^^^^ это правильный путь ^^^ - person David Haim; 15.10.2015

int& mapLL::operator[](std::string key){ 
   int val = this->get(key);
   return val;
}

вы возвращаете ссылку на локальную переменную val.
что вам действительно нужно сделать, так это найти элемент в вашем связанном списке и вернуть его как есть, без присвоения локальным переменным между ними.

Кроме того, list3 — это указатель, к сожалению, вам нужно разыменовать его перед использованием оператора []:

(*list3)["ghi"]; 

все уже сказано + глядя на ваш профиль, я понимаю, что вы родом из Java. Мой совет: поймите, в чем разница между выделением стека и выделением кучи. это самая основа языка. вам нужно использовать динамически размещаемые объекты (= использование new) очень редко.

хотя Java скрывает детали распределения, это, возможно, одна из самых важных тем в C++. не все должно быть указателем. ваша отправная точка - объекты, выделенные стеком. перейдите оттуда к динамическому/статическому распределению, если оно не соответствует вашим потребностям.

person David Haim    schedule 15.10.2015
comment
моей первоначальной идеей было это return this->get(key), но это дало мне эту ошибку invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’ - person cmb; 15.10.2015