Поведение инициализации членов класса примитивного типа - PullRequest
3 голосов
/ 08 ноября 2019

Я знаю, что здесь довольно много ответов на эту тему, но я не смог найти тот, который полностью ответил на мой вопрос.

Ниже я делаю некоторые предположения, основанные на моем понимании инициализации (какC ++ 17). Было бы хорошо, если бы кто-то мог указать / исправить мои ошибки.

Учитывая тип

struct A
{
    int x;  
};

, создание локальной переменной вообще не инициализирует объект

A a;  // a.x is indeterminate, accessing it is UB

Однако мы можем принудительно инициализировать агрегат с помощью следующего

A a{};
A a = {};

, который инициализирует a.x в 0.

Теперь, учитывая тип

struct B
{
    int x;
    std::string s;
};

при создании локальной переменной default инициализируется объект

B b;

, в результате чего b.s инициализируется по умолчанию (потому что это не POD), но b.x неопределен, доступ к нему по-прежнему UB.

Далее у нас есть

struct C
{
    int x = 0;
    std::string s;
};

. Создание локальной переменной по умолчанию инициализирует объект

C c;

, что приводит к инициализации C.s по умолчанию (потому что это неPOD) и c.x при инициализации копирования, поведение хорошо определено.

Наконец, давайте сравним некоторые типы и проверим, имеют ли они идентичное поведение инициализации. Я предполагаю, что нет никакой разницы между этими типами, если я создаю (инициализированную по умолчанию) локальную переменную (A a;).

Случай A

struct A1
{
    int x;  
};

struct A2
{
    A2() { }
    int x;  
};

struct A3
{
    A3() = default;
    int x;  
};

x никогда не инициализируется, это значение не определено.

Случай B

struct B1
{
    int x{};
};

struct B2
{
    B2() : x{} { }
    int x;  
};

struct B3
{
    B3() = default;
    int x = 0;  
};

x всегда инициализируется, его значение равно 0.

Дело C

struct C1
{
    int x;
    std::string s;
};

struct C2
{
    C2() { }
    int x;
    std::string s;
};

struct C3
{
    C3() = default;
    int x;
    std::string s;
};

s всегда инициализируется по умолчанию, но x никогда не инициализируется, его значение не определено.

Являются ли эти утверждения правильными, а если нет, то где ошибки и каково реальное поведение?

1 Ответ

0 голосов
/ 10 ноября 2019

Вы пропустили только одну тонкость: для A3 или C3, запись T3 t{}; или T3() инициализирует x в 0, потому что конструктор по умолчанию, установленный по умолчанию в его первом объявлении, вызывает значениеинициализация для обнуления инициализирует объект и по умолчанию инициализирует его .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...