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

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

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

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

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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.12.2011, 10:25
Ответы с готовыми решениями:

В чём разница в конструкрукторе со списком инициализации и без оного
объясните пожалуйста разницу между конструктором по умолчанию и конструктором по умолчанию. первая...

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

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

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

17
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
06.12.2011, 10:35 2
Цитата Сообщение от 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 3
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
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
06.12.2011, 10:45  [ТС] 4
taras atavin, приведенный код абсолютно нормально компилится gcc, и в нем нет ничего зазорного ни с точки зрения логики ни с точки зрения стандарта.

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

Добавлено через 1 минуту
Цитата Сообщение от oxotnik Посмотреть сообщение
оба случая - дефолтный конструктор
во втором случае сначала вызывается конструктор по умолчанию, а затем только - оператор присваивания
1
Заблокирован
06.12.2011, 10:59 6
Цитата Сообщение от 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
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
06.12.2011, 10:59  [ТС] 7
Цитата Сообщение от PointsEqual Посмотреть сообщение
во втором случае сначала вызывается конструктор по умолчанию, а затем только - оператор присваивания
Имеется ввиду для членов isState...?
0
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
06.12.2011, 11:02 8
Цитата Сообщение от oxotnik Посмотреть сообщение
Имеется ввиду для членов isState...?
да, isState
1
Заблокирован
06.12.2011, 11:03 9
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
145 / 142 / 11
Регистрация: 11.09.2011
Сообщений: 411
06.12.2011, 11:19 10
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 11
Цитата Сообщение от KristopherRobin Посмотреть сообщение
после пойдет выполнение конструктора в котором им присвоятся значения (true, false)
Не правильно. Конструктор вызывается только один раз за время жизни объекта.
Для того, что бы изменить состояние объекта, будит вызван operator=
0
ниначмуроФ
851 / 535 / 110
Регистрация: 12.10.2009
Сообщений: 1,913
06.12.2011, 11:23 12
+ список инициализации - единственный способ инициализации константных членов и членов-ссылок класса

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

C++
1
2
3
4
5
6
7
8
9
class Test
{
public:
    Test(int val): ref(val){}
    int& ref; //как известно, ссылка должна 
                //быть инициализирована явно
                //в другой момент времени
               // задать ей значение нельзя
};
0
1665 / 1134 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1
06.12.2011, 11:38  [ТС] 16
Bers, не понимаю как этот пример использовать:
Код
class Test
{
public:
    Test(int val): ref(val){}
    int& ref;
};

int main()
{
    int i = 100;
    Test(i);
    return 0;
}
так не компилится
а так:
Код
int main()
{
    Test(100);
    return 0;
}
смысл ссылки теряется
0
Заблокирован
06.12.2011, 11:41 17
Цитата Сообщение от 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
oxotnik
06.12.2011, 11:43  [ТС]     Какая разница в инициализации?
  #18

Не по теме:

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

0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.12.2011, 11:43

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

Какая разница?!
Вот две сортировки массивов, если не трудно обьясните пожалуйста разницу и есть ли указатели тут:...

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

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


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru