Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Инициализация константного динамического массива, Каждому элементу свою инициализацию 
V
    Опции темы
JackYF
Дата 10.4.2007, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



likehood, мне надо будет отдавать пользователю ссылки на элементы массива. В данном случае тип элементов foo_local, о котором пользовает не знает и не узнает, так как он локальный.


Цитата(Earnest @  9.4.2007,  20:36 Найти цитируемый пост)
public - данные - вот это некрасиво.

Ну, не всегда. Особенно если они константные...

Цитата(Earnest @  9.4.2007,  20:36 Найти цитируемый пост)
поэтому инициализируй его как хочешь.

чем? уже созданным внешне массивом?

Цитата(Earnest @  9.4.2007,  20:36 Найти цитируемый пост)
инициализируй его как хочешь.

Как хочу? Дык вот я и хочу! Вызвать разные конструкторы для разных элементов массива. Но как? Проблема - инициализация массива!

Цитата(Earnest @  9.4.2007,  20:36 Найти цитируемый пост)
А саму структуру в объемлющем классе сделай константной. 

Ы, тоже не мой выход. Некоторые данные должны остаться public.

Earnest, вариант threef'a не подходит. Он предлагает инициализировать надструктуру. Опять-таки - чем? У меня не POD-данные, чтобы их в инициализаторе прописывать между фигурными скобками... Задача - вызов конструкторов. И без локальных классов, мне потом надо будет эти ссылки на эти данные выводить наружу.

Подводя по крайней мере промежуточный итог, резюмирую... не буду предоставлять public-const данные, сделаю через функции.
Но вот абстрактный вопрос инициализации массива до сих пор не решен. Скорее всего, все-таки нельзя. А жалко.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Earnest
Дата 10.4.2007, 07:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Если массив не константный, то никто не мешает писать в конструкторе структуры:
a[0] = XXX;
a[1] = YYY;
и т.д.
Нужно только позаботиться, чтобы элементы массива имели default-конструкторы.
Что ты передашь в надструктуру для инициализации - твоя проблема, хоть из файла данные читай.
Ты писал изначально о невозможности вызвать конструкторы для каждого элемента массива. Так вот, эта проблема решается в рамках описанного подхода.
А как ты разом передашь для разных элементов инициализирующие данные - совсем другая проблема.


--------------------
...
PM   Вверх
JackYF
Дата 10.4.2007, 14:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Earnest @  10.4.2007,  07:49 Найти цитируемый пост)
a[0] = XXX;
a[1] = YYY;


Operator= не подходит... Уже говорил же ж. Если делать константными данными.

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

Просто абстрагируясь от моей проблемы: как вызвать <u>конструкторы</u> элементов массива. Не присваивания потом или через внешние структуры.
Сам факт. Нет - значит нет, дело же такое smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
likehood
Дата 10.4.2007, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Цитата(JackYF @  10.4.2007,  01:39 Найти цитируемый пост)
likehood, мне надо будет отдавать пользователю ссылки на элементы массива. В данном случае тип элементов foo_local, о котором пользовает не знает и не узнает, так как он локальный.

Вообще-то, в моем примере тип массива Foo*, так что никаких проблем. Приведение к базовому классу еще никто не отменял.
PM MAIL   Вверх
JackYF
Дата 10.4.2007, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(likehood @  10.4.2007,  14:33 Найти цитируемый пост)
Вообще-то, в моем примере тип массива Foo*, так что никаких проблем. Приведение к базовому классу еще никто не отменял. 


Соглашусь. Но проблема прямого вызова конструкторов не решена. Мне надо это запихнуть в массив без operator=. Если выдавать элементы по одному, то такое не выйдет.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
SerpentVV
Дата 10.4.2007, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 27.11.2006
Где: Астрахань

Репутация: 1
Всего: 1



Поля-массивы в классе

До сих пор в качестве полей мы использовали только скалярные переменные. Но в С++ нет запрета объявлять в классе поле-массив. Естественно, размер класса с полем-массивом увеличивается на размер массива. Однако использование массива в классе имеет некоторые нюансы, связанные с инициализацией . Начнем разбираться с этим вопросом на самом простом примере (листинг 2.23), в котором объявляются и инициализируются несколько полей-массивов.

Код

Листинг 2.23. Поля-массивы в классе
class Arrays
{    int m0[10];
    static const unsigned int k = 10;
    enum { n = 10 };
    int m1[k];
    int m2[n];
    public: 
        Arrays() 
        { for (int i = 0; i < k; ++i) m0[i]=m1[i]=m2[i]=0; }
};   

В классе Arrays объявлено три поля-массива: m0, m1 и m2. Как видим, задать количество элементов массива можно либо явной константой, либо константным выражением со статическими и/или нумерованными константами, причем константы должны быть определены раньше массива. Задавать количество элементов поля-массива обязательно.
Конструктор без аргументов обнуляет массивы, выполняя цикл в теле. Такой способ инициализации поля-массива — в теле конструктора — является наиболее простым. Это позволяет присвоить элементам массива любые значения. Однако наиболее часто выполняется обнуление, поэтому для массивов разрешается применять инициализацию нулем. Тогда наш конструктор выглядит значительно проще:
Код

Arrays(): m0(), m1(), m2() {} 

Для массива объектов некоторого типа такая запись означает вызов конструктора по умолчанию (без аргументов), и не забудьте, что этот вызов выполняется для каждого элемента массива.
К сожалению, применение списков инициализации для полей-массивов этим и ограничивается — в скобках нельзя ничего указывать. Явная инициализация не проходит даже для символьных массивов. Например, если мы объявим в классе Arrays символьный массив
Код

char s[4];

и попытаемся в списке инициализации конструктора присвоить этому массиву символьную константу,
Код

Arrays(): m0(), m1(), m2(), s("abc") {}

то в системе Visual C++.NET 2003 получим сообщение об ошибке:
error C2536: 'Arrays::Arrays::s' :
cannot specify explicit initializer for arrays
нельзя определять явный инициализатор для массивов

Однако мы можем прописать в классе поле-указатель на символ
Код

char *s;

и инициализировать его символьной константой в списке инициализации конструктора, как показано выше.
Как это ни странно, но большие проблемы возникают при попытках объявить в классе константный массив встроенного типа! Как мы выяснили выше, константы не могут быть проинициализированы в теле конструктора и инициализируются только в списке инициализации конструктора. Однако для константного массива встроенного типа не работает даже инициализация нулем.
ПРИМЕЧАНИЕ
Этот вопрос практически не отражен в стандарте, поэтому компиляторы ведут себя по-разному. В системе Visual C++.NET 2003 выдается ошибка компиляции C2439, а Borland C++ Builder 6 выдает только предупреждение W8038 о том, что массив не инициализируется.

Не проходит и отмена константности. Например, мы пропишем массив m0 как константный, а в теле конструктора пропишем инициализацию в цикле
Код

for (int i = 0; i < 10; ++i) 
    const_cast<int>(m0[i]) = 0;

И система Visual C++.NET 2003, и Borland C++ Builder 6 откажутся компилировать такой цикл.
Удивительно, но для константного массива объектов не встроенного типа задавать инициализацию нулем разрешается. Для этого в классе должен быть определен конструктор без аргументов, который вызывается для инициализации каждого элемента константного поля-массива. Например, вполне можно инициализировать константный массив строк,
Код

const string ss[10];

прописав в списке инициализации конструктора инициализацию «нулем» ss(). Как реально инициализируется такой массив, конечно, зависит от реализации конструктора по умолчанию.

PM MAIL   Вверх
JackYF
Дата 10.4.2007, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



SerpentVV, это все было к чему?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
likehood
Дата 10.4.2007, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Цитата(JackYF @  10.4.2007,  15:38 Найти цитируемый пост)
Мне надо это запихнуть в массив без operator=.

Может я плохо понял задачу, но в моем примере operator= не используется, присваивание идет через список инициализации.
PM MAIL   Вверх
JackYF
Дата 10.4.2007, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(likehood @  10.4.2007,  15:04 Найти цитируемый пост)
Может я плохо понял задачу

Задача - вызов конструкторов для каждого элемента массива. Список инициализации работает только для POD-типов, тем более значения, передаваемые в конструктор, мне не известны в начале программы.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
likehood
Дата 10.4.2007, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Ну так в моем примере передаваемые значения и вычисляются во время работы программы. Кстати, почему это список инициализации работает только для POD-типов?

Добавлено через 2 минуты и 53 секунды
Может мы говорим о разных вещах? smile
Я говорю об этом посте.
PM MAIL   Вверх
JackYF
Дата 10.4.2007, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(likehood @  10.4.2007,  16:15 Найти цитируемый пост)
Кстати, почему это список инициализации работает только для POD-типов?

Хм... приведи контрпример.

Цитата(likehood @  10.4.2007,  16:15 Найти цитируемый пост)
Ну так в моем примере передаваемые значения и вычисляются во время работы программы.

да... недосмотрел я тогда, видать. Возможно, это выход. Попробую применить. Спасибо.

Ввиду этого дела... там где раньше в постах переборщил, извините... хорошо же меня понесло.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
likehood
Дата 10.4.2007, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Цитата(JackYF @  10.4.2007,  18:41 Найти цитируемый пост)
Возможно, это выход.

Все же локальные классы - довольно экзотическая вещь. Пожалуй, лучшем вариантом будет предложенный Earnest.

Цитата(JackYF @  10.4.2007,  18:41 Найти цитируемый пост)
Хм... приведи контрпример.

Видимо, я тебя неправильно понял. Ты, наверное, под списком инициализации имел ввиду пример threef'а, а я подумал о другом. В таком случае согласен насчет POD-типов.

Цитата(JackYF @  10.4.2007,  18:41 Найти цитируемый пост)
там где раньше в постах переборщил, извините

Разве ж это переборщил. Тут такие перлы иногда выдают...  smile 
PM MAIL   Вверх
SerpentVV
Дата 11.4.2007, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 27.11.2006
Где: Астрахань

Репутация: 1
Всего: 1



Цитата(JackYF @ 10.4.2007,  15:01)
SerpentVV, это все было к чему?

Это к тому, что в списке инициализации вызывается конструктор по умолчанию - для неPOD-типов.

Во-вторых, к тому, что о полях-константных массивах в стандарте нет практически ничего.

В третьих, несколько противоречивая постановка: инициализировать константный массив значениями, которые не известны в начале работы программы...
Тогда это - не константный массив, если значения констант неизвестны при компиляции...

Если есть желание просто защитить от изменений - нет нужны объявлять массив константным... Можно решить этот вопрос на уровне прав доступа...
 
PM MAIL   Вверх
JackYF
Дата 11.4.2007, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(SerpentVV @  11.4.2007,  12:10 Найти цитируемый пост)
инициализировать константный массив значениями, которые не известны в начале работы программы...


Никаких противоречий...

Код

const std::time_t beg_time = std::time();


Такой код тебя не смущает? А ведь значение явно не будет известно на этапе компиляции...
Так и у меня. У меня некоторые поля класса константные... Которые, естественно, инициализируются в конструкторе. Не по-умолчанию...

А в принципе, как минимум два пути решения вопроса уже озвучены.
1) с помощью прав доступа
2) с помощью локальных классов

Всем спасибо, тему можно закрывать.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
SerpentVV
Дата 11.4.2007, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 27.11.2006
Где: Астрахань

Репутация: 1
Всего: 1



Ага, понял... Логическая константность, естественно, не всегда равна физической... smile

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1456 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.