Форум программистов, компьютерный форум CyberForum.ru

Вопрос по коду - C++

Восстановить пароль Регистрация
 
SharpBeginner
0 / 0 / 0
Регистрация: 06.08.2011
Сообщений: 10
03.02.2012, 15:43     Вопрос по коду #1
Здравствуйте ! Есть код односвязного списка, но мне не очень понятны некоторые моменты. Буду очень благодарен опытным людям которые объяснят или покажут в какую сторону копать

Сам код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
class List
{
public:
    struct Node
    {
       Node(const int& data, Node* next=0):data(data),next(next) {}
        Node* next;
        int data;
    };
 
    List() : head(0) {}
 
    List(const List& L) : head(0)
    {
        for ( const Node* i = L.begin(); i!= L.end(); i=i->next )
            push_front(i->data);
        reverse();
    }
 
    void reverse()
    {
        Node* p = 0; Node* i = begin(); Node* n;
        while (i)
        {
            n = i->next;
            i->next = p;
            p = i; i = n;
        }
        head = p;
    }
 
    void swap(List& x)
    {
        Node* tmp = head; head = x.head; x.head = tmp;
    }
 
    List& operator=(const List& x)
    {
        List tmp(x);
        swap(tmp);
        return *this;
    }
 
    ~List() { clear(); }
    void clear() { while (!empty()) pop_front(); }
 
    bool empty() { return ! head; }
 
    void push_front(const int& x) {
        Node* tmp = new Node(x,head); head = tmp;
    }
 
    void pop_front() {
        if (head) { Node* tmp = head; head=head->next; delete tmp; }
    }
 
    void insert_after(Node* x, const int& data)
    {
        Node* tmp = new Node(data, x->next);
        x->next = tmp;
    }
 
    void erase_after(Node* x)
    {
        Node* tmp = x->next;
        if (tmp)
        {
            x->next = x->next->next;
            delete tmp;
        }
    }
 
 
    int& front() { return head->data; }
    const int& front() const { return head->data; }
 
    Node* begin() { return head; }
    Node* end() { return 0; }
 
    const Node* begin() const { return head; }
    const Node* end() const { return 0; }
 
private:
    Node* head;
};
Первый вопрос.

Не понятно что происходит в строке 6: "Node(const int& data, Node* next=0):data(data),next(next) {}". А именно зачем после объявления аргументов дописано ":data(data),next(next)" ?
То же самое касается строк 11 и 13.

ЗЫ: Извините за нубство.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.02.2012, 15:43     Вопрос по коду
Посмотрите здесь:

C++ коментарий к коду..
C++ Вопрос по исходному коду
C++ И снова вопрос по коду
Комментарии к коду C++
объяснения к коду C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
03.02.2012, 15:46     Вопрос по коду #2
Почитайте про конструктор или скажите: что именно не понятно в этих строчках.

Добавлено через 45 секунд
Цитата Сообщение от SharpBeginner Посмотреть сообщение
data(data),next(next)
Так понятней?
C
1
data = data; next = next;
SharpBeginner
0 / 0 / 0
Регистрация: 06.08.2011
Сообщений: 10
03.02.2012, 16:22  [ТС]     Вопрос по коду #3
Насколько я понял, такая запись используется в конструкторах классов для того что бы сократить код .

Добавлено через 6 минут
Еще один вопрос

В строке 80 и 81
const Node* begin() const { return head; }
const Node* end() const { return 0; }

Какое назначение ключевых слов const здесь. Зачем писать 2 раза ?
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
03.02.2012, 16:29     Вопрос по коду #4
C++
1
const Node* begin() const { return head; }
Первое означает, что будет возвращено константное выражение (в данном случае указатель, разадресовать его и присвоить новое значение не получится). Второе означает, что в теле функции не возможно изменение значений (например, каких-либо переменных, в вашем случае head)
SharpBeginner
0 / 0 / 0
Регистрация: 06.08.2011
Сообщений: 10
03.02.2012, 16:48  [ТС]     Вопрос по коду #5
Спасибо большое уважаемый go.
fasked
Эксперт C++
 Аватар для fasked
4925 / 2505 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
03.02.2012, 17:07     Вопрос по коду #6
Цитата Сообщение от SharpBeginner Посмотреть сообщение
Насколько я понял, такая запись используется в конструкторах классов для того что бы сократить код .
Не совсем. Есть и другие тонкости. Такая запись чаще всего оптимальнее в плане эффективности.
Цитата Сообщение от go Посмотреть сообщение
Второе означает, что в теле функции не возможно изменение значений (например, каких-либо переменных, в вашем случае head)
А точнее данных класса. Ну и без модификатора const, данный метод невозможно будет вызвать для константного объекта.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
03.02.2012, 17:14     Вопрос по коду #7
Цитата Сообщение от SharpBeginner Посмотреть сообщение
такая запись используется в конструкторах классов для того что бы сократить код
Нет, для того, чтобы увеличить производительность. Это называется списком инициализации конструктора. В таком списке инициализации можно явно вызывать контрукторы членов-данных класса, а так же только в списке инициализации можно вызывать конструкторы базовах классов и инициализировать поля класса, которые имеют ссылочный тип. Посмотрите на такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Foo
{
public:
    Foo(int foo = 0):
    m_foo(foo)
    {
    }
 
private:
    int m_foo;
};
 
class Bar
{
public:
    Bar(int bar):
    m_bar(bar)
    {
    }
 
private:
    Foo m_bar;
};
Здесь класс Bar содержит объект класса Foo в качестве члена (с именем m_bar). При этом конструктор для этого члена вызывается явно в списке инициализации. Объект инициализируется при создании. А теперь взглянем на такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Foo
{
public:
    Foo(int foo = 0):
    m_foo(foo)
    {
    }
 
private:
    int m_foo;
};
 
class Bar
{
public:
    Bar(int bar)
    {
        m_bar = Foo(bar);
    }
 
private:
    Foo m_bar;
};
Здесь объекту присваивается значение в теле конструктора. Кажется, что всё так же, как и в первом коде. Но это не так. На самом деле конструктор, представленный в данном коде, эквивалентен такому конструктору:
C++
1
2
3
4
5
Bar(int bar):
m_bar()
{
    m_bar = Foo(bar);
}
Таким образом, видно, что производится лишнее действие. Сначала (неявно) вызывается конструктор по умолчанию класса Foo для объекта m_bar, а затем этому объекту явно присваивается значение. В данном случае класс Foo совсем небольшой и его инициализация несущественно отразится на производительности программы, но будь этот объект большим, и будь таких объектов несколько, и это могло бы стать существенной проблемой. Так что есть правило: в теле конструктора производится работа более сложная, чем инициализация, и поэтому всю работу по инициализации следует выносить в список инициализации.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.02.2012, 19:05     Вопрос по коду
Еще ссылки по теме:

Пояснение к коду C++
C++ объяснения по коду
C++ Комментарии к коду

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
04.02.2012, 19:05     Вопрос по коду #8
Цитата Сообщение от fasked Посмотреть сообщение
А точнее данных класса.
А еще точнее, если они не являются mutable.
Yandex
Объявления
04.02.2012, 19:05     Вопрос по коду
Ответ Создать тему
Опции темы

Текущее время: 10:59. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru