Инициализация вектора в конструкторе

260
02 апреля 2017, 04:58
class A {
public:
 A(size_t size):vector(size, default_value){}
private:
 std::vector<int> vector;
 const int default_value = -1;
}

Почему вектор инициализируется рандомным значением? Константа ещё не успевает стать -1? Как тогда сделать правильно?

Answer 1

Да, раз Вы проводите инициализацию в списке инициализации, то надо строчку с константой вынести выше, поскольку операция конструирования полей класса происходит в порядке из записи. У Вас еще неизвестно значение этой константы. Поэтому сделайте минимум так:

class A 
{
public:
A(size_t size)
    : vector(size, default_value) {}
private:
сonst int default_value = -1;
std::vector<int> vector;
}
Answer 2

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

class A {
public:
 A(size_t size):vector(size, default_value){}
private:
 std::vector<int> vector;
 const int default_value = -1;
};

член данных vector инициализируется, когда член данных default_value еще не был инициализирован.

Если переставить эти члены данных местами, то программа будет иметь ожидаемое поведение

#include <iostream>
#include <vector>
class A 
{
public:
    A( size_t size ) : vector( size, default_value ) { }
    friend std::ostream & operator <<( std::ostream &, const A & );
private:
    const int default_value = -1;
    std::vector<int> vector;
};
std::ostream & operator <<( std::ostream &os, const A &a )
{
    for ( int x : a.vector ) std::cout << x << ' ';
    return os;
}

int main() 
{
    A a( 10 );
    std::cout << a << std::endl;
    return 0;
}

Вывод программы на консоль

-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 

Из стандарта C++ (12.6.2 Initializing bases and members)

13 In a non-delegating constructor, initialization proceeds in the following order:

...

  • Then, non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

Если бы вы объявили член данных default_value как статический член данных класса, то тогда инициализация нестатического члена данных vector не зависела бы от порялка объявления этих членов данных, так как статические члены класса инициализируются до создания любого объекта класса.

class A 
{
public:
    A( size_t size ) : vector( size, default_value ) { }
    friend std::ostream & operator <<( std::ostream &, const A & );
private:
    std::vector<int> vector;
    static const int default_value = -1;
};
READ ALSO
Необработанные исключения Stack Overflow

Необработанные исключения Stack Overflow

Необработанные исключения по адресу 0x00821CC9 в пexe: 0xC00000FD: Stack overflow (параметры: 0x00000000, 0x006E2000)

304
Странный синтаксис С++ кода в библиотеке LuaBind

Странный синтаксис С++ кода в библиотеке LuaBind

Заинтересовался либой LuaBindЧитаю доку, разбираю примеры

218
как закрыть окно браузера по его названию и запустить ярлык

как закрыть окно браузера по его названию и запустить ярлык

как закрыть окно браузера по его названию, а потом (если закрытие было) открыть ссылку/ярлык/батник?

195
Переключение между окнами в Qt версии 4.8

Переключение между окнами в Qt версии 4.8

В общем сделал как в примере на сайте https://evilegcom/ru/post/112/

254