Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > перегрузка оператора + для списков


Автор: Vadv 5.10.2008, 23:35
Код

#include <iostream>
using namespace std;
struct list
{    int inf;    // информационное поле
    list *next;    // указатель на следующий элемент списка
};
class spisok
{    list* head;// указатель на начало списка
    int n;//кол-во элементов
public:
    spisok (int);
    spisok (spisok&);
    spisok (list *h);
    void print ();
    spisok operator +(const spisok&);
~spisok();
};
spisok::spisok(list *h)
{
    head=h;
}
spisok::spisok (int n1)
//конструктор инициализирует список из n элементов по принципу
// "очередь"
{    head = NULL;
    n=n1;
    list *p,*pn;
    for (int i = 0; i<n1; i++)
    {    p = new list;
    p->inf = rand()%20+1;
    p->next = NULL;
    if (head == NULL) head = p;
    else  pn->next = p;
    pn = p;
    }
}
spisok::spisok (spisok& s)
//конструктор копии класса spisok 
{    head = NULL;
list *sp = s.head, *p, *pn;
    while (sp)
    {
        p = new list;
        p->inf = sp->inf;
        p->next = NULL;
        if (head == NULL) head = p;
    else pn->next = p;
    pn = p;
    sp = sp->next;
    }
}
spisok::~spisok()
//деструктор - уничтожает объект класса список из памяти 
{    list *p;
    while ( head )
    {    p = head;
    head = head->next;
    delete p;
    }
}
void spisok::print()
{    
    list *p = head;
    while (p)
    {    
        cout<<p->inf<<" ";
        p = p->next;
    }
    cout<<endl;
}
spisok spisok::operator + (const spisok& sp)
{
    head = NULL;
    list *p,*pn,*s=sp.head;
    for (int i = 0; i<n; i++)
    {    
        p = new list;
        p->inf = s->inf;
        p->next = NULL;
        if (head == NULL) head = p;
        else  pn->next = p;
        pn = p;
        s=s->next;
    }
    return *this;
}

void main()
{
    spisok a(5),b(a),c(10);
    a.print();
    cout<<endl;
    b.print();
    c=a+b;
    cout<<endl;
    c.print();
}

Приветствую, товарищи программисты smile. Подскажите пожалуйста, что что не так я делаю в функции перегрузки..

Вывод должен быть таким:
Список 1 : 1 2 3 4 5
Список 2: 3 4 5 6
Список 3=Список1 + Список 2=1 2 3 4 5 3 4 5 6.

Автор: J0ker 6.10.2008, 02:30
Код

spisok spisok::operator + (const spisok& sp) const
{
    spisok ns(sp);
    list h = {0, NULL};
    list *ph = &h;
    for (list *s=head; s; s = s->next)
    {
        ph->next = new list;
        ph->next->inf = s->inf;
        ph = ph->next;
    }
    if(h.next) {
        ph->next = ns.head;
        ns.head = h.next;
        ns.n += n;
    }
    return ns;
}


вроде как-то так... писАл прямо тут - могут быть ошибки

Добавлено @ 02:35
spisok (spisok&); должен быть spisok (const spisok&);
и void print (); должен быть void print () const;
и spisok (list *h); тут ни к чему - он нарушает инкапсуляцию (но см.ниже)

Добавлено @ 02:44
вышеозначенный метод не очень рационален - будет создаваться и разрушаться лишний объект со всеми внутренностями
можно сделать так (пишу только то, что нужно изменить):
Код

class spisok
{
private:
    spisok (list *h, int num);
};
spisok::spisok(list *h, int num)
{
    head=h;
    n = num;
}


spisok spisok::operator + (const spisok& sp) const
{
    spisok ns(sp);
    list h = {0, NULL};
    list *ph = &h;
    for (list *s=head; s; s = s->next)
    {
        ph->next = new list;
        ph->next->inf = s->inf;
        ph = ph->next;
    }
    if(h.next) {
        ph->next = ns.head;
        ns.head = h.next;
        ns.n += n;
    }
    ph = ns.head;
    int num = ns.n;
    ns.head = NULL;
    ns.n = 0;
    return spisok(ph, num);
}


здесь срабатывает return value optimization

Автор: Vadv 6.10.2008, 14:59
J0ker, спасибо большое, вопрос снят!

Автор: UnrealMan 6.10.2008, 16:26
Я б ещё на безопасность к исключениям обратил внимание. Если внутри цикла new выкинет исключение, то непонятно, кто будет освобождать выделенную память.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)