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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 117, средняя оценка - 4.91
RASHFor
6 / 6 / 0
Регистрация: 12.02.2012
Сообщений: 224
#1

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

09.09.2012, 20:23. Просмотров 15840. Ответов 24
Метки нет (Все метки)

1)Любезные,скажите когда надо исп. списки инициализации, а когда можно заменить констуктором по умолчанию?
2) правильно ли утверждение,что списки инициализации можно заменить к.по умолчанию?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.09.2012, 20:23
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Когда надо использовать списки инициализации, а когда можно заменить их констуктором по умолчанию? (C++):

Когда стоит использовать класс, а когда лучше обойтись без них? - C++
Когда стоит использовать класс, а когда лучше обойтись без них? Когда следует использовать несколько классов? Вот, например. Программа...

Когда нужно использовать &ссылки ,а когда *указатели? - C++
Желательно с примерами

Когда использовать WinAPI, а когда функции языка? - C++
Не совсем понимаю, когда нужно использовать WinAPI в приложении, а когда функционал самого ЯП (С/С++). Для той же работы с файлами...

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

Объяснить (с примерами) для чего нужен RTTI, как и когда его можно и нужно использовать - C++
доброго времени суток. вопрос такой как я понял RTTI это свойсвто языка С++ которое было добавлено позднее его релиза, что бы...

Когда создается конструктор по умолчанию? - C++
Здравствуйте, товарищи! Прочитал тут книгу "Ассемблер и дизасеммблирование" Пирогова и открыл для себя такую вещь, что конструктор...

24
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6486 / 3130 / 307
Регистрация: 04.12.2011
Сообщений: 8,645
Записей в блоге: 5
31.01.2015, 22:10 #16
Цитата Сообщение от hoggy Посмотреть сообщение
Ваше "не получится" - это присвоение, а не инициализация.
Холливар? Не интересует.
Цитата Сообщение от hoggy Посмотреть сообщение
Она была и остается обычным мембером класса.
А кто спорит. Но увсех мемберов этого пола:
const int a = 10;
для всех экземпляров будет одно значение: 10
А присвоение при объявлении и в теле конструктора это инициализация. Хотя синтаксически - присвоение.

Не по теме:

В чём источник энергии спора? Любовь к истине?

0
hoggy
6654 / 2842 / 487
Регистрация: 15.11.2014
Сообщений: 6,294
Завершенные тесты: 1
31.01.2015, 23:12 #17
Цитата Сообщение от 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
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6486 / 3130 / 307
Регистрация: 04.12.2011
Сообщений: 8,645
Записей в блоге: 5
01.02.2015, 00:49 #18
Цитата Сообщение от hoggy Посмотреть сообщение
В общем случае это может быть нужно тогда,
когда требуется гарантировать неизменность данных.
Вы говорите о необходимости статических констант? А я спросил о том, зачем может понадобиться куча одинаковых по значению копий (мемберов как вы говорите).
Фраза:
Цитата Сообщение от IGPIGP Посмотреть сообщение
каждый будет иметь свою копию в отличие от настоящей статической константы.
в ней ясно, что речь не о статической константе, а о константе члене. И о бессмысленности её инициализации литералом, а не внешним параметром. Но Вы хотите не увидеть и пишете:
Цитата Сообщение от hoggy Посмотреть сообщение
Она была и остается обычным мембером класса.
Хотя нигде не говорилось иного.
Ещё фраза:
Цитата Сообщение от IGPIGP Посмотреть сообщение
А присвоение при объявлении и в теле конструктора это инициализация. Хотя синтаксически - присвоение.
Тут перечислены 2 случая, но не через запятую а с союзом "и":
a) int a = 123;//глобально, локально, как угодно
б) объявление в классе, а инициализация присвоением в конструкторе. Это вопрос скользкий и в общем случае наверное инициализации тут нет, а есть присваивание. Не буду спорить, - неточно сказал.
Но вопрос ТС:
Цитата Сообщение от RASHFor Посмотреть сообщение
а когда можно заменить конструктором по умолчанию?
оставляет только догадываться о чём он пытался спросить. Возможно о том, что когда в членах определены конструкторы преобразования и не определены конструкторы по умолчанию, то инициализация в списке, это способ гарантирующий инициализацию до вызова любого из методов. Однако, судя по тому как вопрос задан, это наверное и хорошо, что никто не стал об этом говорить. Надеюсь продолжения не будет.
0
Shaman1387
0 / 0 / 0
Регистрация: 24.01.2015
Сообщений: 6
01.02.2015, 01:39 #19
Простое правило, которое использую лично я, если это конструктор в котором просто инициализируются данные, то - это список инициализации, если есть выделение памяти или же какие-то еще нюансы, тогда описываю все в конструкторе, а по-поводу консруктора по-умолчанию, его всегда надо писать по-умолчанию и через тот же список инициализации задавать значения по-умолчанию.
0
hoggy
6654 / 2842 / 487
Регистрация: 15.11.2014
Сообщений: 6,294
Завершенные тесты: 1
01.02.2015, 01:41 #20
Цитата Сообщение от IGPIGP Посмотреть сообщение
Вы говорите о необходимости статических констант? А я спросил о том, зачем может понадобиться куча одинаковых по значению копий (мемберов как вы говорите).
Нет.

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

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

Цитата Сообщение от IGPIGP Посмотреть сообщение
о бессмысленности её инициализации литералом, а не внешним параметром.
Ложь. Изначальный тезис был:

Цитата Сообщение от IGPIGP Посмотреть сообщение
Ведь инициализируя её литералом или другой константой Вы делаете её одинаковой для всех экземпляров.
Я привел пример использования не статического,
и неизменяемого члена класса, который инициализируется другой константой.

Инициализация неизменяемого нестатического члена класса только литералами действительно избыточна,
и не эффективна, поскольку не имеет никаких полезных свойств,
которые нельзя было бы заполучить более эффективным способом:
при помощи локальных статических объектов.

Однако, класс не контролирует источник данных для своих конструкторов.
И не может накладывать на это никаких ограничений.

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

Может быть так:
C++
1
some obj("hello");
может быть так:

C++
1
2
3
static const char* data[] = { .... };
...
some obj(data[index] );
может быть так:

C++
1
some obj( other::class_name  );
или как то ещё.

А в отсутствии ограничений само по себе рассуждение на тему:
"бессмысленности инициализации литералом, а не внешним параметром" - не имеет смысла.

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

Цитата Сообщение от IGPIGP Посмотреть сообщение
Хотя нигде не говорилось иного.
Вы писали:
Цитата Сообщение от IGPIGP Посмотреть сообщение
становится угрожающе статической
Иногда лучше вообще ничего не писать, чем писать "хрень".

Цитата Сообщение от IGPIGP Посмотреть сообщение
Тут перечислены 2 случая, но не через запятую а с союзом "и":
По-моему вы мне мозги полоскаете. Нет?

Цитата Сообщение от IGPIGP Посмотреть сообщение
a) int a = 123;
Это именно инициализация, а не присвоение.

Цитата Сообщение от IGPIGP Посмотреть сообщение
оставляет только догадываться о чём он пытался спросить.
Он не знает материал, поэтому не может сформулировать точно вопрос.

По идее, находится кто нибудь, кто чисто по человечески догадывается (хотя бы примерно) о чем речь.
Ну или переспрашивает, наталкивая новичка на более корректные вопросы...

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

В этом заключается суть "с++ раздел для новичков", разве нет?
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6486 / 3130 / 307
Регистрация: 04.12.2011
Сообщений: 8,645
Записей в блоге: 5
01.02.2015, 01:56 #21
Цитата Сообщение от hoggy Посмотреть сообщение
Это именно инициализация, а не присвоение.
hoggy, я написал что это инициализация с синтаксисом присвоения:
Цитата Сообщение от IGPIGP Посмотреть сообщение
А присвоение при объявлении и в теле конструктора это инициализация.
Вы стали спорить и я показал, что имел ввиду под "присвоение при объявлении " : int a = 123;

И оказалось что:
Цитата Сообщение от hoggy Посмотреть сообщение
Это именно инициализация, а не присвоение.
Давайте так: Вы правы. И всё.
0
player1975
0 / 0 / 0
Регистрация: 14.04.2016
Сообщений: 3
13.09.2016, 11:04 #22
В догонку:
есть несколько типов инициализаций, но что можно сказать про эту инициализацию:
C++
1
      int i=22 ; // direct, copy? (C++98)
И чем
C++
1
        int i=22;
отличается от
C++
1
2
        int i; 
        i=22;
or
C++
1
        int i(22);
А , например,
C++
1
2
3
       Type i1;
       Type i2;
       i2=i1;
отличается от
C++
1
2
       Type i1;
       Type i2=i1;
(Type - пользовательский тип...
0
DrOffset
7321 / 4421 / 1001
Регистрация: 30.01.2014
Сообщений: 7,259
13.09.2016, 14:19 #23
Цитата Сообщение от player1975 Посмотреть сообщение
есть несколько типов инициализаций, но что можно сказать про эту инициализацию:
C++
1
int i=22 ; // direct, copy? (C++98)
copy.
сокращенная запись для
C++
1
int i( int(22) );
Цитата Сообщение от player1975 Посмотреть сообщение
И чем
C++
1
int i=22;
отличается от
C++
1
2
int i;
i=22;
or
C++
1
int i(22);
первое - инициализация (copy), второе - не инициализация, это присваивание, третье - direct initialization.

Цитата Сообщение от player1975 Посмотреть сообщение
А , например,
C++
1
2
3
Type i1;
Type i2;
i2=i1;
отличается от
C++
1
2
Type i1;
Type i2=i1;
Первое - это не инициализация, это присваивание.
Второе - copy initialization, как в первом примере с целыми числами.
0
ИсмаилПркопенко
Заблокирован
17.04.2017, 22:37 #24
Цитата Сообщение от silent_1991 Посмотреть сообщение
IGPIGP, да банальнейший пример - вызов конкретного конструктора базового класса можно сделать только в списке инициализации.
А зачем разработчики языка так сделали?
Какой в этом смысл?
0
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
18.04.2017, 05:49 #25
ИсмаилПркопенко, очень просто. К моменту, когда мы входим в тело конструктора производного класса, та его часть, которая относится к базовому классу, уже должна быть полностью инициализирована. В общем случае только базовый класс знает, как именно должны быть инициализированы его поля, там может быть и простейшая инициализация конкретными значениями, и очень сложная работа, вплоть до, например, получения данных для инициализации по сети. А инициализация производного класса может (и зачастую будет) зависеть от значений, установленных в процессе инициализации базового класса. Более того, конструкторы базовых классов будут вызваны до инициализации любых полей производного класса, в том числе когда инициализация происходит через список инициализации, потому что в этом случае также может возникнуть зависимость.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.04.2017, 05:49
Привет! Вот еще темы с ответами:

Когда запускаю и ввожу параметры, то, в момент когда программа должна выполнять действие, пишет ошибку - C++
Недавно начали изучать c++. так как в школе не было программирования (преподу пофиг было) я в универе отстаю ;c Написал программу по...

Перестало выводить, когда задание списков перевел в конструкторы, когда были просто функции выводило нормально. - C++
Не могу понять почему не выводит список на экран Перестало выводить, когда задание списков перевел в конструкторы, когда были просто...

Записать условия когда является истинным , когда: - C++
Записать условия когда является истинным , когда: целое N кратно четырем и не оканчивается нулем Привет всем вот мой код но он у меня...

Когда используется * перед указателями, а когда нет? - C++
Вообщем я запутался и не пойму, когда нужно перед указателем ставить &quot;*&quot;, а когда нет. Как я понял, &quot;*&quot; ставится перед указателем,...


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

Или воспользуйтесь поиском по форуму:
25
Yandex
Объявления
18.04.2017, 05:49
Ответ Создать тему
Опции темы

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