Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1

Какая разница в инициализации?

06.12.2011, 10:25. Показов 2729. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть класс:

C++
1
2
3
4
5
6
class CSomeClass
{
    CSomeClass();
private:
    bool isState1, isState2;
};
члены isState1, isState2 можно инициализировать 2-мя способами:
C++
1
2
3
4
5
// 1-й
CSomeClass::CSomeClass()
: isState1(true), isState2(false)
{
}
C++
1
2
3
4
5
6
//2-й
CSomeClass::CSomeClass()
{
    isState1 = true;
    isState2 = false;
}
Какая между ними разница? В смысле, в даном случае никакой не вижу, но если классы потом будут наследоваться, видоизменяться и т.д., то какой способ предпочтительней? Или при любом способе монопенисуально?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.12.2011, 10:25
Ответы с готовыми решениями:

В чём разница в конструкрукторе со списком инициализации и без оного
объясните пожалуйста разницу между конструктором по умолчанию и конструктором по умолчанию. первая запись: Circle(float _x = 0.0,...

Разница в определении конструкторов со списком инициализации и без него
Начинаю изучать конструкторы , и в моей книге его объявление выглядит следующим образом class Counter { private : unsigned int...

Различные варианты инициализации указателя - в чём точная разница между ними?
Немного непонятен один момент. Есть некий класс Statement (конструктор используется по умолчанию). Вот четыре различных записи...

17
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
06.12.2011, 10:35
Цитата Сообщение от oxotnik Посмотреть сообщение
CSomeClass::CSomeClass()
: isState1(true), isState2(false)
Эта форма предназначена для вызова конструкторов предков isState1 и isState2, то есть isState1 и isState2 - классы-предки isState1. Соответственно удивляет тот компилятор, который проглотит эту форму при
Цитата Сообщение от oxotnik Посмотреть сообщение
class CSomeClass
, то есть без таких предков.
Цитата Сообщение от oxotnik Посмотреть сообщение
CSomeClass::CSomeClass()
{
isState1 = true;
isState2 = false;
}
В том случае, когда нет наследования, эта форма - единственная, иначе она не возможна, так как класс-потомок (в отличие от композита) просто не имеет членов с такими именами.
0
Заблокирован
06.12.2011, 10:41
1 случай: инициализация данных членов.

2 случай: инициализация данных членов дефолтными конструкторами, а потом присвоение им уже других значений.

В результате - падение производительности.

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

Если данные члены - примитивные типы данных, то возможно разницы не будит никакой (нужно смотреть ассм код)

Добавлено через 2 минуты
Цитата Сообщение от taras atavin Посмотреть сообщение
Эта форма предназначена для вызова конструкторов предков isState1 и isState2, то есть isState1 и isState2 - классы-предки isState1. Соответственно удивляет тот компилятор, который проглотит
ничего подобного:

C++
1
2
3
4
5
6
CScreenForm::CScreenForm(cSize_a x, cSize_a y, const char Char):
CColorTextForm(x,y,Char),  //конструктор папочки
myParent(NULL_PTR),          //данные-члены
myVisible(VISIBLE),            //данные-члены
myActive(ACTIVE_OBJ)       //данные-члены
{/*пуст за ненадобностью*/}
0
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
06.12.2011, 10:45  [ТС]
taras atavin, приведенный код абсолютно нормально компилится gcc, и в нем нет ничего зазорного ни с точки зрения логики ни с точки зрения стандарта.

Добавлено через 1 минуту
Цитата Сообщение от Bers Посмотреть сообщение
1 случай: инициализация данных членов. 2 случай: инициализация данных членов дефолтными конструкторами, а потом присвоение им уже других значений.
не совсем понял... оба случая - дефолтный конструктор (класса), разница только в способе (месте инициализации)
0
ниначмуроФ
 Аватар для PointsEqual
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
06.12.2011, 10:54
Цитата Сообщение от oxotnik Посмотреть сообщение
но если классы потом будут наследоваться, видоизменяться и т.д., то какой способ предпочтительней?
первый, тк
единственный способ вызвать конструкторы родительских классов с определёнными параметрами - список инициализации

Добавлено через 1 минуту
Цитата Сообщение от oxotnik Посмотреть сообщение
оба случая - дефолтный конструктор
во втором случае сначала вызывается конструктор по умолчанию, а затем только - оператор присваивания
1
Заблокирован
06.12.2011, 10:59
Цитата Сообщение от oxotnik Посмотреть сообщение
не совсем понял... оба случая - дефолтный конструктор (класса), разница только в способе (месте инициализации)
Проиллюстрируем на примере:
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
class Test
{
public:
    Test(): myVal(0){std::cout<<"Defolt\n";}
    Test(int val): myVal(val){ std::cout<<"Arg\n";}
    Test(const Test& rhs) { std::cout<<"Copy\n";}
 
    void operator=(int val) { myVal=val; std::cout<<"operator=\n"; }
private:
    int myVal;
};
 
class Agregat1
{
public: 
    Agregat1():myTest(333){}
    Test myTest;
};
 
class Agregat2
{
public: 
    Agregat2() {myTest = 333;}
    Test myTest;
};
 
 
int main()
{
    //HELLO;
 
    Agregat1 test1;
    
    std::cout<<"======\n";
    Agregat2 test2;
 
//вывод:
//Arg
//======
//Defolt
//operator
 
}
Таким образом во втором случае время тратится сначала на дефолтную инициализацию, а потом на присвоением с помощью operator=
1
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
06.12.2011, 10:59  [ТС]
Цитата Сообщение от PointsEqual Посмотреть сообщение
во втором случае сначала вызывается конструктор по умолчанию, а затем только - оператор присваивания
Имеется ввиду для членов isState...?
0
ниначмуроФ
 Аватар для PointsEqual
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
06.12.2011, 11:02
Цитата Сообщение от oxotnik Посмотреть сообщение
Имеется ввиду для членов isState...?
да, isState
1
Заблокирован
06.12.2011, 11:03
oxotnik, а есть ситуации, когда не получится просто так вызвать конструктор базового класса, даже если очень хочется, и остаётся лишь прибегать к услугам туловища конструктора потомка:
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
class Children;
class Parent
{
public:
 
    Parent():mPtr(NULL){} 
    Parent(Children& src):mPtr(&src){}
 
    void Init(Children& src) { mPtr=&src;}
 
    Children* mPtr;
};
 
class Children:public Parent
{
public:
    Children():Parent(*this) //выстрел в ногу! 
      //warning C4355: this: использован в списке
      // инициализации базового класса
    {  
        Init(*this);  //вот так правильно
    }
    
    Parent* mPtr;
};
1
 Аватар для KristopherRobin
146 / 143 / 11
Регистрация: 11.09.2011
Сообщений: 419
06.12.2011, 11:19
1й случай это типа инициализация конструктора в памяти заведутся переменные сразу со занчениями (true, false) после чего пойдет выполнение конструктора.

2й тут заведутся переменные со случайными значениями (т.е. в переменных будут просто данные которые хранились в этой области памяти до того как переменные заняли эту область), после пойдет выполнение конструктора в котором им присвоятся значения (true, false)

в книгах советуют первый способ т.к. он быстрее. а еще таким способом нужно вызывать конструкторы базового класса с аргументами.

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
class A
{
public: 
    A() {};
    A(int NewA); //как в унаследованных классах вызывать именно этот конструктор?
 
    int VarA;
};
 
class B: public A //наследуем класс А
{
public:
    B() {};
    B(int NewA, int NewB);
 
    int VarB;
};
 
A::A(int NewA):VarA(NewA)
{
}
 
B::B(int NewA, int NewB):A(NewA),VarB(NewB)  //вызов конструктора класса А с аргументом
{
 
}


C++
1
2
3
B::B(int NewA, int NewB):VarA(NewA),VarB(NewB) //попытка инициализоровать переменную базового класса без конструктора. переменная еще не появилась - не был вызван констурктор базового класса, а мы ее уже пытаемся инициализировать, поэтому вылезет ошибка
{
}

C++
1
2
3
4
5
B::B(int NewA, int NewB)  //вызовется конструктор базового класса A() без агрументов
{
    VarA = NewA; //И только после этого можно пристваить переменной значение
    VarB = NewB;
}
C++
1
2
3
4
B::B(int NewA, int NewB):A(NewA),VarB(NewB)  //вызов конструктора класса А с аргументом
{
                                                  //самый быстрый вариант
}
0
Заблокирован
06.12.2011, 11:22
Цитата Сообщение от KristopherRobin Посмотреть сообщение
после пойдет выполнение конструктора в котором им присвоятся значения (true, false)
Не правильно. Конструктор вызывается только один раз за время жизни объекта.
Для того, что бы изменить состояние объекта, будит вызван operator=
0
ниначмуроФ
 Аватар для PointsEqual
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
06.12.2011, 11:23
+ список инициализации - единственный способ инициализации константных членов и членов-ссылок класса

вроде преимуществ больше нет
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
06.12.2011, 11:25
А с какого предок вообще знает, что нужно потомку и как его инитить? Предок должен быть описан так, чтобы допускать отсутствие потомков с заранее заданными декларациями, твой инит - способ засунуть свою голову себе же в рот и подвесить кувалду возле челюсти. А если чилдрен не будет иметь определённого расширяющего члена? А ты в parent::init к нему уже обратился. А если потом ты решишь, что тот комплекс значений полей, которые parent::init в них запишет, не допустим? Но поведение parent::init уже стало частью реализации другого класса. А если ты потом закроешь расширяющий член? А parent::init уже к нему обращается. А если числдрен придётся переименовать? Но предку он уже известен под этим именем и под ним внесён в член предка.
0
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
06.12.2011, 11:26  [ТС]
Цитата Сообщение от PointsEqual Посмотреть сообщение
членов-ссылок класса
вот здесь поподробней, на примере... не представяю себе член-ссылку
0
Заблокирован
06.12.2011, 11:32
Цитата Сообщение от oxotnik Посмотреть сообщение
вот здесь поподробней, на примере... не представяю себе член-ссылку

C++
1
2
3
4
5
6
7
8
9
class Test
{
public:
    Test(int val): ref(val){}
    int& ref; //как известно, ссылка должна 
                //быть инициализирована явно
                //в другой момент времени
               // задать ей значение нельзя
};
0
 Аватар для oxotnik
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
06.12.2011, 11:38  [ТС]
Bers, не понимаю как этот пример использовать:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
class Test
{
public:
    Test(int val): ref(val){}
    int& ref;
};
 
int main()
{
    int i = 100;
    Test(i);
    return 0;
}
так не компилится
а так:
Code
1
2
3
4
5
int main()
{
    Test(100);
    return 0;
}
смысл ссылки теряется
0
Заблокирован
06.12.2011, 11:41
Цитата Сообщение от oxotnik Посмотреть сообщение
смысл ссылки теряется
да это просто пример, как можно инициализировать ссылку.
Ну можно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Test
{
public:
    Test(int& val): ref(val){}
    int& ref; //как известно, ссылка должна быть инициализирована явно
    //в другой момент времени задать ей значение нельзя
};
 
int main()
{
    //HELLO;
 
    int a=10; //настоящий пассажир остался снаружи
    Test t(a); //а ссылка на него внутри объекта
    EndProgramm();
}
0
06.12.2011, 11:43  [ТС]

Не по теме:

ой, блин, ступил немного

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
06.12.2011, 11:43
Помогаю со студенческими работами здесь

Инициализация в теле конструктора или в списке инициализации, есть ли разница в сгенерированном коде?
Инициализация в теле конструктора или в списке инициализации - большая ли разница в сгенерированном коде? И есть ли она вообще?

Какая разница?
Я уже довольно долго изучаю С++ и столкнулся с проблемой: чем отличается cout от printf, так как я всегда пользовался cout, не могу понять...

Какая разница?!
Вот две сортировки массивов, если не трудно обьясните пожалуйста разницу и есть ли указатели тут: bool foo(double i,double j) { ...

Какая Разница между сортировками?
Какая разница между сортировками, если в итоге все виды сортируют одинаково. Т е. Результат одинаковый

Какая разница между двумя алгоритмами?
Вообщем, как только я свою задачу не упрощал, но в указанные ограничения она так и не входит. Сначала был лимит памяти, теперь лимит...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru