Может ли переменная-член получить доступ к значению ранее определенной переменной-члена в том же списке инициализации (C ++)? - PullRequest
0 голосов
/ 09 ноября 2018

Например:

Cls::Cls(int *p) : m1_(1), m2_(m1), m3_(p), m4_(m3) {}

, где Cls::m1_ и Cls::m2_ относятся к типу int, а m3 и m4 относятся к типу int*.

Это законно? Если это законно, делает ли он то, что ожидал?

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Как указано в комментариях, нестатические элементы данных инициализируются в порядке объявления . Чтобы избежать путаницы, вы должны всегда записывать инициализаторы членов в порядке объявления. Поэтому в случае, представленном в вопросе, я предполагаю, что порядок, в котором были объявлены члены:

int m1_;
int m2_;
int* m3_;
int* m4_;

Предполагая, что это так, код четко определен и выполняет то, что вы ожидаете. Это гарантируется [intro.execution] /12.3, который гарантирует, что каждая инициализация члена является полным выражением, и [class.base.init] /13.3, который гарантирует, что эти инициализации происходят в порядке объявления.

0 голосов
/ 09 ноября 2018

Это законно. Если у вас есть

struct foo
{
    int a;
    int b;
    int c;
    foo() : a(1), b(a + 1), c(b + 1) {}
};

Тогда это нормально. Причина в том, что a объявлено в классе до b, а b объявлено до c. Все члены класса инициализируются в том порядке, в котором они объявлены в классе, так что вы даже можете получить

struct foo
{
    int a;
    int b;
    int c;
    foo() : c(b + 1), b(a + 1), a(1) {}
};

и с тобой все будет в порядке. Если бы у вас было

struct foo
{
    int b;
    int c;
    int a;
    foo() : a(1), b(a + 1), c(b + 1) {}
};

с другой стороны, b и c будут инициализированы с неопределенным значением, и их использование будет неопределенным поведением.

0 голосов
/ 09 ноября 2018

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

struct C
{
    C() : m1_(1), m2_(m1_ + 1), m3_(m2_ + 2), m4_(m3_ + 3) {} 

    int m1_ = 0;
    int m2_ = 0;
    int m3_ = 0;
    int m4_ = 0;
};

int main()
{
    C c;
    std::cout << c.m1_ << std::endl;
    std::cout << c.m2_ << std::endl;
    std::cout << c.m3_ << std::endl;
    std::cout << c.m4_ << std::endl;
}

Выход:

1
2
4
7

Но если вы изменили членские ордера:

struct C
{
    C() : m1_(1), m2_(m1_ + 1), m3_(m2_ + 2), m4_(m3_ + 3) {} 

    int m2_ = 0;
    int m3_ = 0;
    int m4_ = 0;
    int m1_ = 0;
};

Вывод будет:

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