LINUX.ORG.RU

перегрузка операции на c++


0

0

Возникла проблема. Необходимо написать функции вставки/удаления элемента в связном списке, следующего после элемента с номером n. Чтобы это организовать необходимо перегрузить операцию []. Написанный мной кусок конечно же зависает. Но где ошибки?

elem operator[](int n)

{

elem *p; /* elem - структура */

p = first; /* first - указатель на начало списка */

for(int i = 0; i < n; i++)

{

if(p == NULL)

{ printf(«нет такого элемента\n»);

} else {

while(p != NULL) {

p = p->link;

}

}

}

return *p;

};


перепости с тегом [code][/code]

lester ★★★★ ()

В операторе добавляйте новый элемент в список по нужному индексу и возвращайте ссылку на его данные.

Циклы у вас какие-то не такие. Один фор, в нем i++ и p=p->next.

staseg ★★★★★ ()
Ответ на: комментарий от staseg

ну цикл по i отсчитывает просто до нужного элемента, а p->link осуществляет сам переход

Holly ()
Ответ на: комментарий от Holly

Что он должен делать, понятно, но у вас p всегда улетит в конец списка. Эту штуку нужно организовать в одном цикле.

И, как я писал, возвращайте int&, тогда этим пользоваться будет удобно:

list[5]=42;

//Вообще говоря назначение такого оператора [] совсем не очевидно, лучше сделать функцию insert.

staseg ★★★★★ ()
Ответ на: комментарий от lester

Перепощу за ленивого топикстартера.

elem operator[](int n){
  elem *p; /* elem - структура */
  p = first; /* first - указатель на начало списка */

  for(int i = 0; i < n; i++){
    if(p == NULL){
      printf("нет такого элемента\n");
    } else {
      while(p != NULL) {
        p = p->link;
      }
    }
  }

  return *p;
};
anonymous ()
elem operator[](int n) {
    elem *p; /* elem - структура */
    p = first; /* first - указатель на начало списка */
    // assert(p)?

    while (n--) {
        // assert(p->link)? Хотя наверное лучше хранить где-нибудь размер списка и уже проверять n < size.
        p = p->link;
    }

    /* Что если n < 0? Возвращаем *first? */
    /* Вообще да, как уже сказали выше, возвращать нужно ссылку. */
    return *p;
}
rival ★★ ()
Ответ на: комментарий от anonymous

спасибо,

p = first;
for( size_t i = 0 ; i < n && p ; p = p->next, ++i )
lester ★★★★ ()
Ответ на: комментарий от rival

Мм, тут проверка в цикле неправильная. Нужно следить, чтобы n > 0.

rival ★★ ()
Ответ на: комментарий от anonymous

Упрощение:

 
elem operator[] (int n) { 
  elem *p;   /* elem - структура */ 
  p = first; /* first - указатель на начало списка */ 
 
  for (int i = 0; i < n; i++) 
    if (p == NULL) 
      printf("нет такого элемента\n"); 
    else  
      while (p != NULL)  
        p = p->link; 

  return *p; 
}; 

Только я так и не врубился, как связаны i и *p.

hibou ★★★★★ ()
Ответ на: комментарий от hibou
while (p != NULL)   
  p = p->link;  

Ну и что эта херня должна вернуть, по-твоему?

anonymous ()
Ответ на: комментарий от anonymous

Из кода мне непонятно. Я у него только скобки лишние поубирал.

hibou ★★★★★ ()
Ответ на: комментарий от rival
while (n--) { 
        // assert(p->link)? Хотя наверное лучше хранить где-нибудь размер списка и уже проверять n < size. 
        p = p->link; 
    } 

p = null; p = p->link //segsigv

Assert не работает, если определено NDBUG

anonymous ()
Ответ на: комментарий от staseg

Она есть, просто закомментирована =). Почему там вообще должен быть 0? Вышли за пределы? Ну так я и написал, что нужно сравнивать с size, либо assert на каждом шаге цикла. Не, можно и проверку на null, но что в таком случае возвращать?

rival ★★ ()
Ответ на: комментарий от staseg

lester все правильно написал, но я надеялся, ТС сама к этому придет.

staseg ★★★★★ ()
Ответ на: комментарий от anonymous

> Assert не работает, если определено NDBUG

Ок, буду знать.

rival ★★ ()
Ответ на: комментарий от rival

NULL, очевидно же. А за ассерт надо отрывать что-нибудь.

anonymous ()
Ответ на: комментарий от anonymous

> list[5]=42;

elem operator[](int n)

NULL



И как оно будет работать?


А за ассерт надо отрывать что-нибудь.


Почему? Потому что он не всегда работает? В каких вообще случаях тогда нужно использовать ассерты?

rival ★★ ()
Ответ на: комментарий от rival

>Почему? Потому что он не всегда работает?

Yep.

В каких вообще случаях тогда нужно использовать ассерты?

А хз, я прямо на вскидку не прикину ситуаций, где рассыпаться только в дебажной сборке надо, проще тогда в дебагер брякнуться по user breakpoint.

anonymous ()
Ответ на: комментарий от rival

И как оно будет работать?

item* p = list[ 5 ];
if( p ) *p = 42

если не хочется возится с указателями - возвращай:

static item dummy;
return p ? *p : dummy;

В каких вообще случаях тогда нужно использовать ассерты?

у меня обычно идет связка - проверка + ассерт( мой собственный без всяких abort'ов ), ассерты в релизной сборке отключены

lester ★★★★ ()
Ответ на: комментарий от lester

>если не хочется возится с указателями - возвращай:

Там же ссылка возвращается, он, я так понял, имел ввиду что-то вроде
coollist list[5];
list[125] = «ololo!»;

тогда можно просто бросать исключение, например.

anonymous ()
Ответ на: комментарий от anonymous

Да, до указателей я догадался, но меня этот вариант не устроил. А вот вариант с dummy понравился.

Исключения, я всегда про них забываю, так как как-то не привык их использовать в cpp коде, и видимо я читал какие-то левые сорцы, раз они мне почти не попадались.

rival ★★ ()
Ответ на: комментарий от rival

> Да, до указателей я догадался, но меня этот вариант не устроил

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

lester ★★★★ ()
Ответ на: комментарий от rival

>И как оно будет работать?

В случае операции «вставка элемента» при большем, чем положено, значении N, вполне можно просто остановиться, добавить новый элемент в конец и вернуть ссылку на данные в нем.

staseg ★★★★★ ()
Ответ на: комментарий от hibou

Только я так и не врубился, как связаны i и *p.


они вообще не должны быть связаны

Boy_from_Jungle ★★★★ ()
Ответ на: комментарий от Boy_from_Jungle

Ага, ну я больше на си пишу. Плюсы пока не очень знаю.

hibou ★★★★★ ()
Ответ на: комментарий от hibou

> Ага, ну я больше на си пишу. Плюсы пока не очень знаю.

ты клоун - от С++ тут только самая первая строка, остальное голый С

lester ★★★★ ()
Ответ на: комментарий от lester

Нет, клоун это ты, особенно в человеческом плане. Но в С++ надо тебе отдать должное, ты довольно хорошо разбираешься. С другой стороны, если это твоя специальность - то еще бы ты не разбирался! Для меня программирование лишь инструмент, не основная специальность.

Хорошо, я действительно не понимаю строку " p = p->link; ". Догадка конечно есть, но все-равно.

hibou ★★★★★ ()
Ответ на: комментарий от hibou

> особенно в человеческом плане.

я хоть не страдаю поцреотизмом и комплексами

Но в С++ надо тебе отдать должное, ты довольно хорошо разбираешься


это не так - весьма поверхностно

Хорошо, я действительно не понимаю строку " p = p->link; "


ты на С только hello world писал?

lester ★★★★ ()
Ответ на: комментарий от lester

я хоть не страдаю поцреотизмом и комплексами

Давай оставим твой «поцреотизм» хотя бы в этой теме. Хотя я готов сказать, что к ура-потреотам не отношусь. Ладно, тут давай не будем. Что касается моей оценки тебя, то я думаю, тебе она не интересна и, более того, ничем тебе в жизни не поможет. С человеческой точки зрения я тебе ничем не помогу, ну а с модераторской - я уже не модерирую. Так что, я думаю, нет смысла ее здесь высказывать.

Что касается темы, то я вот сейчас просмотрел еще раз внимательно и да, в прошлый раз упустил малость эти 2 строчки:

 elem *p; /* elem - структура */
 p = first; /* first - указатель на начало списка */

Здесь только моя невнимательность. Прошу прощения за «взбаламучивание».

hibou ★★★★★ ()
Ответ на: комментарий от hibou

> Давай оставим твой «поцреотизм» хотя бы в этой теме

это чуть-ли не первый раз, когда я начал эту волынку, а не ты

С человеческой точки зрения я тебе ничем не помогу

ну а с модераторской - я уже не модерирую.



прям импотенция во все поля

Здесь только моя невнимательность


невнимательность - это когда один раз не заметил, а когда подряд несколько раз, да на примере в 10 строк - это называется по-другому

lester ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.