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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.66
_Cherep_
1 / 1 / 0
Регистрация: 02.08.2012
Сообщений: 15
#1

Отличие объявления, определения и инициализации - C++

26.06.2013, 23:57. Просмотров 3882. Ответов 42
Метки нет (Все метки)

Здравствуйте, товарищи.

Читаю тут книжицу по C++, учусь потихоньку.
И возник у меня вопрос нерядового характера: в чём фундаментальное отличие объявления, определения и инициализации? В книге всё намешано, ничего не понятненько.

Однако усёк, что они говаривают, будто такая строка:
C++
1
int a = 3;
не просто присваивание переменной значения, а что-то большее.
И как-то это связано с созданием экземпляров классов.

А ещё пишут, что есть инициализация прямая и инициализация копии.
А потом вот это кажут:
C++
1
2
int val = 1024;
int val (1024);
И говаривают, будто val в обоих случаях будет одинаковой.

Что-то я видно не секу истинной сути.
Помогите словцом мудрым.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.06.2013, 23:57     Отличие объявления, определения и инициализации
Посмотрите здесь:

C++ Что за объявления переменных?
C++ объявления
C++ Объявления массива.
C++ Объявления классов
C++ Особенность объявления функции
объявления друг в друге C++
Ошибки объявления C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
27.06.2013, 13:14     Отличие объявления, определения и инициализации #21
Цитата Сообщение от Croessmah Посмотреть сообщение
задание начального правильного значения, а это и есть инициализация
Тогда дейстие в коде (15 пост) можно назвать инициализацией (с применением механизма присваивания)?
Цитата Сообщение от Croessmah Посмотреть сообщение
но только различие в том, какой механизм используется - механизм инициализации или механизм присвоения
Отличие в том, что в механизме инициализации используются конструкторы?
Croessmah
Модератор
Эксперт CЭксперт С++
12702 / 7176 / 801
Регистрация: 27.09.2012
Сообщений: 17,701
Записей в блоге: 2
Завершенные тесты: 1
27.06.2013, 13:50     Отличие объявления, определения и инициализации #22
@alsav22, Ну на счет механизмов это я просто так выразился, корректнее, наверное, сказать по другому:
C++
1
int a(1024);//инициализация
C++
1
2
int a;//создаем со значением по умолчанию (в данном случае с мусором)
a=1024;//не инициализация, а присвоение начального значения.
имхо, так будет правильнее
второй случай - инициализация с точки зрения определения инициализации и присвоение с точки зрения языка.
С классами же все совершенно очевидно, ибо при создании будет вызван конструктор, который и должен инициализировать объект, а при присвоении будет вызван оператор присвоения.
SatanaXIII
Супер-модератор
Эксперт С++
5578 / 2612 / 239
Регистрация: 01.11.2011
Сообщений: 6,422
Завершенные тесты: 1
27.06.2013, 14:05     Отличие объявления, определения и инициализации #23
Я прошу прощения если не в тему, но нельзя ли перефразировать так:
C++
1
int a;//инициализация мусором
?

Croessmah
Модератор
Эксперт CЭксперт С++
12702 / 7176 / 801
Регистрация: 27.09.2012
Сообщений: 17,701
Записей в блоге: 2
Завершенные тесты: 1
27.06.2013, 14:10     Отличие объявления, определения и инициализации #24
@SatanaXIII, Как, правило, нельзя, ибо нет никакой инициализации - просто выделение места с тем значением, которое будет в памяти валяться то есть создание без задания какого-либо значения, имхо.
SatanaXIII
Супер-модератор
Эксперт С++
5578 / 2612 / 239
Регистрация: 01.11.2011
Сообщений: 6,422
Завершенные тесты: 1
27.06.2013, 14:26     Отличие объявления, определения и инициализации #25
Цитата Сообщение от Croessmah Посмотреть сообщение
то есть создание без задания какого-либо значения, имхо.
то есть создание без задания какого-либо конкретного значения
Убежденный
Системный программист
Эксперт С++
14890 / 6708 / 1059
Регистрация: 02.05.2013
Сообщений: 10,998
Завершенные тесты: 1
27.06.2013, 14:45     Отличие объявления, определения и инициализации #26
Цитата Сообщение от SatanaXIII Посмотреть сообщение
int a;//инициализация мусором
Это не всегда верно.
Для объектов со статическим временем жизни (static storage duration)
выполняется так называемая инициализация нулем (zero-initialization).
C++
1
2
3
4
5
6
7
8
int a; // Будет равно нулю.
 
int main()
{
    int b; // А вот здесь будет мусор.
 
    return 0;
}
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
27.06.2013, 14:51     Отличие объявления, определения и инициализации #27
Цитата Сообщение от Croessmah Посмотреть сообщение
С классами же все совершенно очевидно, ибо при создании будет вызван конструктор, который и должен инициализировать объект
Предположим, был вызван конструктор по умолчанию, который ничего не сделал и в полях объекта остался мусор. Объект всё равно считается инициализированным? Или нет? Почему тогда:
C++
1
int a; // неинициализированный объект
Ведь то же самое (может даже и конструктор по умолчанию вызывается).
Croessmah
Модератор
Эксперт CЭксперт С++
12702 / 7176 / 801
Регистрация: 27.09.2012
Сообщений: 17,701
Записей в блоге: 2
Завершенные тесты: 1
27.06.2013, 14:57     Отличие объявления, определения и инициализации #28
@alsav22, Конструктор предназначен для инициализации объекта. Он вызван, значит объект можно назвать инициализированным, а то, что программист делает в конструкторе всем наплевать главное, чтобы порносайты при этом не открывались
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
27.06.2013, 14:58     Отличие объявления, определения и инициализации #29
Цитата Сообщение от Убежденный Посмотреть сообщение
int b; // А вот здесь будет мусор.
В общем случае, да. Но на старинном ваткоме в отладочном режиме инициализировалось нулями, насколько я помню. Да и https://ideone.com/uGgHt1 дает 0. Короче говоря, "мусорное" значение вполне детерминированно может быть нулём. Но безусловно это всё не регламентируется стандартом.
Убежденный
Системный программист
Эксперт С++
14890 / 6708 / 1059
Регистрация: 02.05.2013
Сообщений: 10,998
Завершенные тесты: 1
27.06.2013, 15:26     Отличие объявления, определения и инициализации #30
Цитата Сообщение от Tulosba Посмотреть сообщение
Но безусловно это всё не регламентируется стандартом.
Если быть совсем дотошным, то вот:
C++ 2003

8.5 Initializers

...

6. Every object of static storage duration shall be zero-initialized at program
startup before any other initialization takes place.

...

9. If no initializer is specified for an object, and the object is of (possibly cv-qualified)
non-POD class type (or array thereof), the object shall be default-initialized; if the
object is of const-qualified type, the underlying class type shall have a user-declared
default constructor. Otherwise, if no initializer is specified for a non-static
object, the object and its subobjects, if any, have an indeterminate initial value
.
Croessmah
Модератор
Эксперт CЭксперт С++
12702 / 7176 / 801
Регистрация: 27.09.2012
Сообщений: 17,701
Записей в блоге: 2
Завершенные тесты: 1
27.06.2013, 15:54     Отличие объявления, определения и инициализации #31
Если вспомнить книгу Макконнелла, то если переменной при создании не задается значение и она содержит мусор, то это неверная инициализация
IGPIGP
Комп_Оратор)
6366 / 3013 / 297
Регистрация: 04.12.2011
Сообщений: 8,102
Записей в блоге: 3
27.06.2013, 16:23     Отличие объявления, определения и инициализации #32
Цитата Сообщение от Croessmah Посмотреть сообщение
неверная инициализация
Неверных инициализаций не бывает. То есть взаимно это как-то.
Вообще, для новичка такие вещи как объявление, определение и инициализация, - предварительное объявление, как и многое другое. Нельзя язык учить как букварь, многое можно понять значительно позже ознакомления.
@_Cherep_, объявление это информация для компилятора для формирования кода. С местом объявления связаны: время жизни, видимости, действия переменной, например.
Определение - информация компилятору и редактору связей для конкретизации значения или адреса.
Инициализация - совмещение, того и другого. Тема большая. Вам пока достаточно понять, что константы и ссылки, невозможно объявить без инициализации. А уж как работают конструктора при инициализации или присваивании это лучше читать и спрашивать конкретно.
Catstail
Модератор
22148 / 10622 / 1729
Регистрация: 12.02.2012
Сообщений: 17,667
27.06.2013, 16:47     Отличие объявления, определения и инициализации #33
В C++ есть такие понятия:

1) объявление (декларация)
2) определение (дефиниция)

Пояснить что есть что, проще всего на примере функций:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int F1(int a);
{
    int i,j;
    ...
    j=F2(i);
 
    return ...
}
 
int F2 (int x)
{
 ...
}

Этот код не скомпилируется, т.к. в момент компиляции F1 компилятор ничего не знает про F2.
Чтобы код скомпилировался, функцию F2 нужно предварительно объявить (декларировать):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int F2(int);  // Декларация F2
 
int F1(int a);
{
    int i,j;
    ...
    j=F2(i);
 
    return ...
}
 
int F2 (int x)  // Дефиниция F2 (определение)
{
 ...
}
Другой вариант: разместить определение F2 перед F1:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int F2 (int x)  // Дефиниция F2 (определение)
{
 ...
}
 
int F1(int a);
{
    int i,j;
    ...
    j=F2(i);
 
    return ...
}
Теперь декларация не нужна (поскольку всякая дефиниция является одновременно и декларацией).

Ну, а инициализация - это присвоение объекту или переменной некоего значения в момент создания.
Croessmah
Модератор
Эксперт CЭксперт С++
12702 / 7176 / 801
Регистрация: 27.09.2012
Сообщений: 17,701
Записей в блоге: 2
Завершенные тесты: 1
27.06.2013, 16:47     Отличие объявления, определения и инициализации #34
@IGPIGP, Откопал у Макконнелла
Неверная инициализация данных - один из плодородных источников ошибок в программировании. Эффективные способы предотвращения проблем с инициализацией могут значительно ускорить отладку.
При неверной инициализации проблемы объясняются тем, что переменная имеет не то первоначальное значение, которое вы ожидаете. Это может случиться по одной из следующих причин.
- Переменной не было присвоено значения. Она имеет то случайное значение, которое находилось в соответствующих ячейках памяти при запуске программы.
- Значение переменной устарело. Когда-то переменной было присвоено значение, но оно утратило свою актуальность.
- Одним частям переменной были присвоены значения, а другим нет.
IGPIGP
Комп_Оратор)
6366 / 3013 / 297
Регистрация: 04.12.2011
Сообщений: 8,102
Записей в блоге: 3
27.06.2013, 17:43     Отличие объявления, определения и инициализации #35
Цитата Сообщение от Croessmah Посмотреть сообщение
Неверная инициализация данных - один из плодородных источников ошибок в программировании.
Это правда. Тем не менее может же быть случай когда переменная должна быть объявлена и не может быть проинициализирована полностью. Например если классы связны указателями друг на друга.
Новичку это ненужно. :
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
#include <iostream>
#include <string>
#include <typeinfo.h>
using namespace std;
class A {
int a;
double b;
string c;
public:
    A()
        :a(1), b(2.0), c("a anb b were sitting on a pipe")  
    {}
A(int a_)//частично инициализирует
:a(a_)
{}
A(double b_)//частично инициализирует
:b(b_)
{}
A(string c_)//частично инициализирует
:c(c_)
{}
A(const A& orig)//копирующий (и полностью инициализирующий)
:a(orig.a), b(orig.b), c(orig.c)
{}
    int& propertyA(){
return a;
}
    double& propertyB(){
return b;
}
string& propertyC(){
return c;
}
};
int main()
 {
     A *b=new A;//динамическая память выделена но не инициализирована
     cout<<b->propertyA()<<endl;//мусор если конструктор по умолчанию (без параметров) закоментирован
 
     A a;//память на стеке выделена
     cout<<a.propertyA()<<endl;////мусор если конструктор закоментирован
     a.propertyA()=2;// заполняется простым присваиванием
     a.propertyB()=5.0;// заполняется простым присваиванием
     a.propertyC()="a+b= ";// заполняется простым присваиванием
     
     cout<<a.propertyA()<<endl;
     cout<<a.propertyB()<<endl;
     cout<<a.propertyC()<<a.propertyA()+a.propertyB()<<endl;
 
     A c(a);//A c = a; - аналогично, полноценность инициализации определяется полноценность конструктора копии
 
     cout<<c.propertyA()<<endl;
     cout<<c.propertyB()<<endl;
     cout<<c.propertyC()<<a.propertyA()+a.propertyB()<<endl;
 
     A d = "Oi scolco musora budet esli razremite stroki nige...";//работает конструктор преобразования принимающий строку
     //остальные поля не инициализированы
     //отложенную, частичную инициализацию можно использовать для связывания двух экземпляров классов, когда
     //один из них обявлен опережающим объявлением, но не может быть полностью инициализирован без указателя на
     //второй, а второму для создания экземпляра нужен указатель на первый
     //такую штуку (создание пары связянных объектов разных классов можно описать в глобальном или статическом методе
     //или написать для этого отдельный класс.
     cout<<d.propertyC()<<endl;
     //cout<<d.propertyA()<<endl;
     //cout<<d.propertyB()<<endl;
     system("pause");
     }
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
27.06.2013, 17:49     Отличие объявления, определения и инициализации #36
Цитата Сообщение от IGPIGP Посмотреть сообщение
Например если классы связны указателями друг на друга.
В таком случае следует инициализировать неким нулевым значением, которое будет четко говорить, что поле не инициализировано. А не оставлять его в "мусорном" состоянии. Например должно быть как минимум так:
C++
1
2
3
A(int a_)//частично инициализирует
:a(a_), b(0) // c - не нужно, т.к. std::string инициализируется конструктором по умолчанию
{}
Croessmah
Модератор
Эксперт CЭксперт С++
12702 / 7176 / 801
Регистрация: 27.09.2012
Сообщений: 17,701
Записей в блоге: 2
Завершенные тесты: 1
27.06.2013, 17:55     Отличие объявления, определения и инициализации #37
Не нужно новичку?
Да ТС, наверное, уже в шоке от всей нашей писанины
IGPIGP
Комп_Оратор)
6366 / 3013 / 297
Регистрация: 04.12.2011
Сообщений: 8,102
Записей в блоге: 3
27.06.2013, 18:01     Отличие объявления, определения и инициализации #38
Цитата Сообщение от Tulosba Посмотреть сообщение
В таком случае следует инициализировать неким нулевым значением,
Может и правда. А если, ход выполнения одного из методов инициализации зависим от значения поля? Или поле - файловый поток, например?
Конечно если слить такие классы в один, то такой вопрос обходится, а если не нет? У меня маловато опыта, чтобы сказать определённо.

Добавлено через 4 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
Да ТС, наверное, уже в шоке от всей нашей писанины
Не может быть. Сейчас заметил: в заголовке typeinfo,h забыл удалить и вообще сырой кусок.
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
27.06.2013, 18:03     Отличие объявления, определения и инициализации #39
Цитата Сообщение от IGPIGP Посмотреть сообщение
А если, ход выполнения одного из методов инициализации зависим от значения поля?
Ради бога. Пусть зависит. Главное чтобы объект был в согласованном состоянии, т.е. сохранятся инвариант класса.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.06.2013, 18:39     Отличие объявления, определения и инициализации
Еще ссылки по теме:

C++ Архитектура правильного определения и объявления класса
Правила объявления инициализации C++
Способы объявления шаблона C++
C++ Вылетает из-за объявления указателя
C++ В чём отличие разных способов объявления переменных?

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

Или воспользуйтесь поиском по форуму:
IGPIGP
Комп_Оратор)
6366 / 3013 / 297
Регистрация: 04.12.2011
Сообщений: 8,102
Записей в блоге: 3
27.06.2013, 18:39     Отличие объявления, определения и инициализации #40
Цитата Сообщение от Tulosba Посмотреть сообщение
Главное чтобы объект был в согласованном состоянии, т.е. сохранятся инвариант класса.
Это безопаснее конечно, но немного дольше. Разве нет?
Yandex
Объявления
27.06.2013, 18:39     Отличие объявления, определения и инициализации
Ответ Создать тему
Опции темы

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