newbie: C ++ вопрос о списках инициализации - PullRequest
2 голосов
/ 21 августа 2009

Допустим, у меня есть массив объектов, объявленных в моем заголовке. Размер массива может быть очень большим. В моем исходном файле я создаю конструктор для своего класса, и я хотел бы инициализировать все объекты в моем массиве. Если эти объекты не создаются с помощью конструктора с нулевым параметром, мне говорят, что их нужно поместить в мой список инициализации.

У меня вопрос: не хочу ли я использовать цикл для инициализации этого, возможно, большого массива объектов, который не попадет в список инициализации? Я не хотел бы помещать в мой список инициализации: str1 ("1"), str2 ("2"), ..., strn ("n"). Может ли цикл для инициализации всех этих объектов идти в заголовке или, возможно, в теле конструктора?

Пожалуйста, дайте мне знать. Я не видел пример этого.

Спасибо, JBU

Ответы [ 6 ]

6 голосов
/ 21 августа 2009

Вы не можете выполнить цикл в списке инициализатора, однако нет проблем с циклом в теле конструктора, если у типа объекта есть допустимый оператор присваивания. Объекты в массиве будут сначала инициализированы с использованием их конструктора с нулевым параметром перед телом конструктора. Затем в теле вы будете назначать их тем, кем они должны быть.

Также обратите внимание, что если каждый объект в массиве должен быть инициализирован с использованием одного и того же NON-нулевого конструктора параметра, вы можете использовать тип std :: vector, а в списке инициализатора указать ненулевой конструктор по умолчанию используется при выделении внутреннего массива, то есть:

// in .h

class MyClass
{
...
    MyClass();

private:

    vector<SomeObject> objects;
};

// in .cpp

MyClass::MyClass()
: objects(100,SomeObject(10, "somestring"))
{
}
5 голосов
/ 21 августа 2009

вам придется подождать, пока C ++ 0x инициализирует массив в списке инициализаторов.

struct S { 
    int a[3]; 
    S(int x, int y, int z) :a{x,y,z} { /*…*/ }; // solution to old problem 
};
4 голосов
/ 21 августа 2009

Можно сделать это с помощью boost назначить вектор констант элементов:

#include<vector>
#include<iostream>
#include<boost/foreach.hpp>
#include<boost/assign.hpp>
#include<boost/assign/list_of.hpp>
#include<boost/assign/std/vector.hpp>

using namespace std;
using namespace boost;
using namespace boost::assign;

typedef vector<int> int_vector;

const int_vector my_const_vector = list_of
(1)(2)(3)(5)(8)(13)(21)(34)(55)(89);

class myClass
{
    public :
      // initialization list used in the constructor
      myClass(const int_vector & vec) 
        : m_member_vector(int_vector(vec.begin(), vec.end())) 
      {}
      void print() const 
      { 
           BOOST_FOREACH(int i, m_member_vector) 
           { cout << i << endl; } 
      }
    private :
      int_vector m_member_vector;
};

void main()
{
   myClass m(my_const_vector);
   m.print();
}

Вы можете получить повышение от здесь . Я понимаю, что это не массивы, но это решает вашу проблему - в некотором смысле

1 голос
/ 21 августа 2009

Вы не можете инициализировать массивы в списке инициализации. Вы должны сделать это в теле конструктора.

Если объект, который вы хотите иметь, не может быть создан по умолчанию, самое простое решение - использовать std :: vector вместо необработанного массива. Таким образом, вы можете создавать элементы, добавляя их в тело конструктора.

Но если вы настаиваете на том, чтобы в качестве члена класса был необработанный массив объектов, тип которых не имеет конструктора по умолчанию, тогда единственный реальный вариант - сделать его массивом указателей на Foo, а не массивом Foo. .

0 голосов
/ 22 августа 2009

По вашему вопросу похоже, что вы хотели бы инициализировать каждый элемент массива другим параметром (как следует из списка str1 ("1"), str2 ("2"), strn ("n") ). Это невозможно с текущим C ++; И, как заметил ТимВ, C ++ 0X позволит поддерживать этот тип инициализации через конструкторы последовательностей.

Сказав это, кажется, что вы хотите сделать, это инициализация во время выполнения этих значений ("1"), ("2") ... ("n") (Знаете ли вы эти значения во время компиляции ?). Если это так, я не думаю, что вы можете использовать список инициализации даже в C ++ 0X. Если это не так (передача параметров времени компиляции для этого очень большого массива), то путь препроцессора - это путь.

0 голосов
/ 21 августа 2009

Не ответ "новичка", и я бы его не использовал, но вы можете взглянуть на библиотеку boost preprocessor , которая позволяет создавать циклы с препроцессором.

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