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

Когда надо использовать списки инициализации, а когда можно заменить их констуктором по умолчанию? - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Работа со строками, поиск нужных элементов и их вывод http://www.cyberforum.ru/cpp-beginners/thread649180.html
Дана строка, состоящая из групп нулей и единиц. Подсчитать количество единиц в группах с нечетным количеством символов. Вот попробовал, но не работает, и ошибки не вижу :-| int i,Length; char...
C++ TreeView в visual c++ Здравствуйте уважаемые форумчане! Недавно начал программировать не только для процесса получения образования, но и для себя. Пишу небольшое графическое приложение в MS Visual C++ Express работающее с... http://www.cyberforum.ru/cpp-beginners/thread649169.html
С++ Шахматная доска C++
Помогите пожалуйста с заданием. Нужно сделать шахматную доску 16*16 и пользователь должен ввести координаты звездочек которые расположатся на доске. Потом программа должна найти кратчайший путь из...
C++ Работа с БД + Поиск по БД C++
Всем привет форумчане! Звучит так "Система учета успеваемости студентов" Тобишь к программе прилагается БД любая хоть MySQL. Что делает программа? Обычный пользователь может вбить туда студента...
C++ Заполнение массива случайным числом http://www.cyberforum.ru/cpp-beginners/thread649112.html
Забыл указать, что нужно вещественное число А и B - правый и левый диапазоны. ar = A + rand() % (B - A + 1); А если число вещественное?
C++ Заполнение массива случайным числом Простите забыл указать. Как заполнить массив случайным вещественным. А и B - правый и левый диапазоны. ar = A + rand() % (B - A + 1); А если число вещественное? подробнее

Показать сообщение отдельно
hoggy
6646 / 2832 / 485
Регистрация: 15.11.2014
Сообщений: 6,256
Завершенные тесты: 1
31.01.2015, 23:12
Цитата Сообщение от RASHFor Посмотреть сообщение
1)Любезные,скажите когда надо исп. списки инициализации, а когда можно заменить констуктором по умолчанию?
Область применения списка инициализации:
когда возникла необходимость определить конструктор.



Если пользовательский конструктор вам не нужен, очевидно что и списки тоже не нужны.

Цитата Сообщение от RASHFor Посмотреть сообщение
2) правильно ли утверждение,что списки инициализации можно заменить к.по умолчанию?
Вопрос звучит примерно так:
"правильно ли утверждение, что колесо автомобиля можно заменить автомобилем?"

Добавлено через 10 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
Холливар?
Правила языка с++

Цитата Сообщение от IGPIGP Посмотреть сообщение
const int a = 10;
для всех экземпляров будет одно значение: 10
Ну и что? Смысли к чему это было сказано?

Цитата Сообщение от IGPIGP Посмотреть сообщение
А присвоение при объявлении и в теле конструктора это инициализация. Хотя синтаксически - присвоение.
Во-первых, в теле конструктора нет никаких объявлений мемберов.
Мемберы объявляются в декларации класса.

А во-вторых:

http://rextester.com/OHL21223


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
//Title of this code
//g++  4.8.2
 
#include <iostream>
 
 
struct value
{
    value()
        :v(0)
    { 
        std::cout<<"value: я был создан и проинициализирован нулем\n"; 
    }
    
 
    value& operator=(int a) 
    {
        std::cout<<"value: изменяю значение на новое: "<< a<<'\n';
        v = a;
        return *this;
    }
    
    int v;
             
             
};
 
 
struct example
{
    example()
        :v()
    {
        std::cout<<"example: запустился мой конструктор\n";
        v = 100;    
    }
    value v;
};
 
int main()
{
    example();
}
Называть инициализацией то, что не имеет к ней ни малейшего отношения - это либо неопытность, и тогда это пройдет.
Либо глупость. А это уже не лечится.

Цитата Сообщение от IGPIGP Посмотреть сообщение
Но может где-то и нужно такое. Расскажите где.
В общем случае это может быть нужно тогда,
когда требуется гарантировать неизменность данных.

Но при этом в силу того, что источник данных может быть различным для различных экземпляров,
то необходимо обеспечить уникальность данных для каждого экземпляра.

Например, мне попадалась задача, где были ноды, которые по задаче не могли существовать без родителя,
и не могли его поменять на протяжении своей жизни.
А самого родителя могли использовать только для чтения.
Но не для изменения.
И поэтому, я использовал const reference.
-------------------------------------------------------------------

Ещё бывают случаи, когда есть внешние статические неизменяемые данные.
А конкретные объекты-потребители в целях оптимизации держат на них лишь ссылки/указатели.

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

------------------------------------
В целом же, просто здравый смысл:
если у класс есть объект который по смыслу должен быть неизменным - он делается константным.
Это как минимум улучшает читабельность.

В коде это могло бы выглядеть примерно так:

http://rextester.com/HUAX7966

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
//Title of this code
//g++  4.8.2
 
#include <iostream>
 
struct simulator //<--- предположим это некий механизм симуляции чего-то
{
    const int param; //<--- отвечает за какой то важный параметр симуляции
          //он константен, поскольку разработчики сочли важным свойством: 
          //он ни при каких обстоятельствах не должен измениться
    
    const char* name; //<--- имя никогда 
         //ни при каких обстоятельствах не должно измениться
    
    template<class T>
    simulator(const T& programm) //<--- механизм получает неккую "программу симуляции"
        :param(T::ID)              // которую и должен отыгрывать.
        ,name(T::getName())
    {
        std::cout<<"симулятор: загрузка программы завершена\n";
            std::cout<<"симулятор: программа: '" << name<<"'\n";
        std::cout<<"симулятор: идентификационный номер: " << param<<'\n';
        
    }
    
    void work()const
    {
        std::cout<<"симулятор: запускаю симуляцию ... '"<<name<<"'\n";
    }
};
 
struct live
{
    enum { ID = 1 };
    static const char* getName() { return "жизнь"; }
};
 
struct virus
{
    enum { ID = 2 };
    static const char* getName() { return "вирус"; }
};
 
 
int main()
{
    std::cout << "Hello, world!\n";
    
    simulator( live() ).work();
    std::cout << "-----------------------------\n";
    simulator( virus() ).work();
}
Обратите внимание:
разные экземпляры класса simulator используют разные источники данных для name.

Но изменять содержимое объекта на который указывает name нельзя ни при каких обстоятельствах.
Потому что изменение объектов являющихся константами от рождения - есть UB.

Автор кода помечает name квалификатором const, что бы гарантировать это положение.
0
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru