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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Инициализация константных полей 
:(
    Опции темы
yep
Дата 6.8.2008, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Есть класс с константным полем. Есть другой класс, который содержит статический массив из первого класса. Как инициализировать константные поля первого класса значением, переданным аргументом конструктора второго класса?
Это выглядит типа
Код

class Class1
{
  const N;
  //...
public:
  Class1(int i): N=i {}
  //...
};

class Class2
{
  Class1 c1[20];
  //...
  public:
  Class2(int i); // значением i надо инициализировать константу каждого элемента массива c1
  //...
};


Это сообщение отредактировал(а) yep - 6.8.2008, 19:35
PM MAIL   Вверх
mes
Дата 6.8.2008, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  6.8.2008,  18:57 Найти цитируемый пост)
  Class1 c1[20];
  //...
  public:
  Class2(int i); // значением i надо инициализировать константу каждого элемента массива c1

так не пройдет , так как массив требует конструктора без параметров..
как обходной вариант : создать динамический массив
П.С.  непойму.. Вы вручную собирались задавать значения всем 20 объектам, а если бы их было 2000 ?



--------------------
PM MAIL WWW   Вверх
Alek86
Дата 6.8.2008, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

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



вообще-то константность и убрать можно на крайняк

но лучше динамический массив

а еще лучше вектор


--------------------
user posted image    user posted image
PM MAIL   Вверх
mes
Дата 6.8.2008, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(Alek86 @  6.8.2008,  19:39 Найти цитируемый пост)
а еще лучше вектор 

а  вектор примет класс у которого нет конструктора без параметров ??

Добавлено через 1 минуту и 41 секунду
Цитата(Alek86 @  6.8.2008,  19:39 Найти цитируемый пост)
вообще-то константность и убрать можно на крайняк

крайняк это когда часть кода чужая.. smile 
А в данном случае помойму проблема с проектировкой  smile 


--------------------
PM MAIL WWW   Вверх
Alek86
Дата 6.8.2008, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

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



если есть конструктор копирования, то никуда он не денется

Код
vect.push_back(Class1(1));



--------------------
user posted image    user posted image
PM MAIL   Вверх
yep
Дата 6.8.2008, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



В моём случае размер массива 10, и менять его никогда не придётся (в частности, поэтому и хочу его оставить статическим). Конечно, 10 элементов можно и вручную проинциализировать, но меня интересует как это делать по-нормальному. 

"так не пройдет , так как массив требует конструктора без параметров.."
т.е. нельзя проиницилизировать по отдельности?
Ничего необычного в этом не вижу и полагал, что это возможно, но попытавшись это сделать типа
Class2::Class2(int i): c1[0]=i
возникает ошибка error C2059: syntax error : '['.
PM MAIL   Вверх
mes
Дата 6.8.2008, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  6.8.2008,  20:00 Найти цитируемый пост)
т.е. нельзя проиницилизировать по отдельности?

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


--------------------
PM MAIL WWW   Вверх
yep
Дата 8.8.2008, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А как установить статический массив?
полагаю, надо сначала выделить необходимую память для соответсвующего указателя, а потом присвоить циклом new Class1(value)

написал так:
Код

class Class1
{
  const N;
  //...
public:
  Class1(int i): N=i {}
  //...
};

class Class2
{
  Class1 *c1;
  //...
  public:
  Class2(int value);
  //...
};

Код

Class1::Class1(int value)
{
  c1 = (Class1 *)malloc(sizeof(Class1)*10);
  for(int i=0; i<10; ++i)
  {
     Class1 *p = c1+i;
     p = new Class1(value);
  }
}


Но возникает ошибка времени выполнения. Если подход правильный, то в чём ошибка? И как написать c1 = (Class1 *)malloc(sizeof(Class1)*10); через new?

Это сообщение отредактировал(а) yep - 8.8.2008, 18:04
PM MAIL   Вверх
mes
Дата 8.8.2008, 18:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  8.8.2008,  17:56 Найти цитируемый пост)
Код

Class1::Class1(int value)
{
  c1 = (Class1 *)malloc(sizeof(Class1)*10);
  for(int i=0; i<10; ++i)
  {
     Class1 *p = c1+i;
     p = new Class1(value);
  }


ужос.. (не говоря об опечатке в названии конструктора smile )

Цитата(Alek86 @  6.8.2008,  19:39 Найти цитируемый пост)
а еще лучше вектор 


Код

class Class2
{
  std::vector<Class1> m_vect;
  //...
  public:
  Class2(int i) { for (int j=0; j<10; ++j ) m_vect.push_back(Class1(i)); } ; // значением i надо инициализировать константу каждого элемента массива c1
  //...
};





Это сообщение отредактировал(а) mes - 8.8.2008, 18:58


--------------------
PM MAIL WWW   Вверх
andrew_121
Дата 8.8.2008, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

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



По моему сдесь ошибка:
Код

Class2::Class2(int value) // Class2
{
  c1 = new Class1[value]; // malloc зачем???
  for(int i=0; i< value; ++i)
  {
     Class1 *p = c1+i; // Что-то непонятное. Помоему ошибка проектирования.
     p = new Class1(value);
  }
}



--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
yep
Дата 8.8.2008, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(mes @ 8.8.2008,  18:56)
ужос.. (не говоря об опечатке в названии конструктора smile )

Цитата(Alek86 @  6.8.2008,  19:39 Найти цитируемый пост)
а еще лучше вектор 


Код

class Class2
{
  std::vector<Class1> m_vect;
  //...
  public:
  Class2(int i) { for (int j=0; j<10; ++j ) m_vect.push_back(Class1(i)); } ; // значением i надо инициализировать константу каждого элемента массива c1
  //...
};

Насчёт вектора тоже самое представил. Но подумал сделать так. Наверно сделаю вектором. А что значит ужос?

Добавлено через 13 секунд
Цитата(andrew_121 @  8.8.2008,  18:59 Найти цитируемый пост)
c1 = new Class1[value]; // malloc зачем???

такая запись, вероятно, создаст не десятиэлементыный массив, проинициализированный value, а создаст массив из value элементов, проинициализированных конструктором по умолчанию.
Цитата(andrew_121 @  8.8.2008,  18:59 Найти цитируемый пост)
Class1 *p = c1+i; // Что-то непонятное. Помоему ошибка проектирования.

Сначала я выделил необходимую память, а потом начал её заполнять, при помощи указателя p.

Понял в чём ошибка. Ошибся, что использовал new в строке p = new Class1(value); надо было *p = Class1(value);
PM MAIL   Вверх
mes
Дата 9.8.2008, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  8.8.2008,  23:52 Найти цитируемый пост)
А что значит ужос?

Код


Class1::Class1(int value) // опечаткa (Class2::Class2)
{
  c1 = (Class1 *)malloc(sizeof(Class1)*10); // выделяем место размером в 10 объектов типа class1 (а хотели выделить под 10 указателей ? )
  for(int i=0; i<10; ++i)
  {
     Class1 *p = c1+i; // циклично сдвигаем указатель по выделенной памяти с шагом равным размеру class1(a не размеру указателя)
     p = new Class1(value); //в то место которое выделили под объект записываете значение указателя, на новый объект
  }
}

Цитата(yep @  8.8.2008,  23:52 Найти цитируемый пост)
Понял в чём ошибка. Ошибся, что использовал new в строке p = new Class1(value); надо было *p = Class1(value); 


а самое плохое в том, что сами не осознаете что делаете.. вот в этом то и ужос ! 

Старайтесь писать проще.. не надо выдумывать ничего заоблачного и все само собой станет понятно ..  smile 



Это сообщение отредактировал(а) mes - 9.8.2008, 00:10


--------------------
PM MAIL WWW   Вверх
yep
Дата 9.8.2008, 00:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Я то прекрасно осознаю, просто ошибся в строке. После исправления ужос исчерпан?
PM MAIL   Вверх
mes
Дата 9.8.2008, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  9.8.2008,  00:10 Найти цитируемый пост)
После исправления ужос исчерпан? 

если исправлением называется это :
Цитата(yep @  8.8.2008,  23:52 Найти цитируемый пост)
 надо было *p = Class1(value); 


то нет 



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


Шустрый
*


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

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



Цитата(mes @  9.8.2008,  00:07 Найти цитируемый пост)
Старайтесь писать проще.. не надо выдумывать ничего заоблачного и все само собой станет понятно ..  

Можно поконкретнее что здесь является заоблачным создание массива или проектировка? Проектировка мне нравится и считаю её удобной, надо было только преодолеть этот момент, который уже видимо преодолён.

Добавлено через 3 минуты и 4 секунды
Цитата(mes @  9.8.2008,  00:07 Найти цитируемый пост)
самое плохое в том, что сами не осознаете что делаете.. вот в этом то и ужос ! 
Цитата(mes @  9.8.2008,  00:12 Найти цитируемый пост)
После исправления ужос исчерпан? если исправлением называется это :Цитата(yep @  8.8.2008,  23:52 ) надо было *p = Class1(value); то нет 

Что именно на ваш взгляд я не осознаю в своём коде?

Добавлено через 4 минуты и 46 секунд
Говорят new безопаснее malloc'a. Остался не отвеченным вопрос: как запись (Class1 *)malloc(sizeof(Class1)*10) через new?

Добавлено через 12 минут и 34 секунды
Цитата(mes @  9.8.2008,  00:07 Найти цитируемый пост)
c1 = (Class1 *)malloc(sizeof(Class1)*10); // выделяем место размером в 10 объектов типа class1 (а хотели выделить под 10 указателей ? )

Нет хотел выделить именно под 10 объектов типа class1. Указатель используется для заполнения этой выделенной памяти
PM MAIL   Вверх
mes
Дата 9.8.2008, 00:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  9.8.2008,  00:15 Найти цитируемый пост)
о здесь является заоблачным создание массива или проектировка

способ создания массива:
1. использование malloc - это си-стиль который не приветствуется в с++ и категорически неприемлим для выделения памяти под неплоские объекты (те у которых есть конструктор) - а именно это происходит во второй строчке кода
2.  c1 - указывает на массив объектов, а  не на массив указателей - что подтверждает пункт 1
3.  c1+i  - про это писалось выше
4.   p = new Class1(value);  - тут правильно все создается , только p указывает совершено не туда куда надо..
Самое интересное что это будет работать.. вот поэтому я и назвал ужос...

Добавлено через 2 минуты и 37 секунд
Цитата(yep @  9.8.2008,  00:15 Найти цитируемый пост)

Что именно на ваш взгляд я не осознаю в своём коде?


Цитата(yep @  9.8.2008,  00:15 Найти цитируемый пост)

Нет хотел выделить именно под 10 объектов типа class1. Указатель используется для заполнения этой выделенной памяти 

вот и ответ.. не понимаете как работает new, чем отличается от malloc, да и вобше какие бывают способы расположения обьектов в памяти 


--------------------
PM MAIL WWW   Вверх
yep
Дата 9.8.2008, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Повторяю, я прекрасно осознаю, что написал. С чего вы решили, что если я и хотел выделить память по объекты класс1, то я чего-то не осознаю? Программа работает как надо.
Цитата(mes @  9.8.2008,  00:28 Найти цитируемый пост)
1. использование malloc - это си-стиль который не приветствуется в с++ и категорически неприемлим для выделения памяти под неплоские объекты (те у которых есть конструктор) - а именно это происходит во второй строчке кода

Поэтому я и спросил как эту строку записать при помощи new

Добавлено @ 00:41
Цитата(mes @  9.8.2008,  00:07 Найти цитируемый пост)
Class1 *p = c1+i; // циклично сдвигаем указатель по выделенной памяти с шагом равным размеру class1(a не размеру указателя)

а здесь что не так? я так и задумал заполнили кусок памяти равный класс1, сдвинулись на класс1 дальше, заполнили следующий кусок...

Добавлено @ 00:44
Цитата(mes @  9.8.2008,  00:28 Найти цитируемый пост)
не понимаете как работает new, чем отличается от malloc, да и вобше какие бывают способы расположения обьектов в памяти 

??? с чего вы взяли?

Добавлено @ 00:45
я использовал malloc только(!) потому что не знаю как это написать через new, как я уже неоднократно писал

Добавлено @ 00:48
c1 = (Class1 *)malloc(sizeof(Class1)*10);
если написать c1 = new Class1[10], даже если будет конструктор по умолчанию это будет, насколько я понимаю, лишняя трата времени на создание 10 объектов, которые всё равно придётся пересоздавать с нужным конструктором

Это сообщение отредактировал(а) yep - 9.8.2008, 00:49
PM MAIL   Вверх
mes
Дата 9.8.2008, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  9.8.2008,  00:36 Найти цитируемый пост)
я использовал malloc только(!) потому что не знаю как это написать через new, как я уже неоднократно писал 

вот удовлетворяю Ваше любопытство.. тот способ про который Вы спрашивали (но не советую использовать)
Код

class C2
{
    Class1 * p_c1;
    public:
     C2 (int i) { p_c1 = (Class1*) operator new (sizeof(Class1)*10);
             for (int j=0; j<10; ++j) new (&p_c1[j]) Class1(i); }

};



--------------------
PM MAIL WWW   Вверх
UnrealMan
Дата 9.8.2008, 02:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  9.8.2008,  00:28 Найти цитируемый пост)
использование malloc - это си-стиль который не приветствуется в с++ и категорически неприемлим для выделения памяти под неплоские объекты (те у которых есть конструктор) 

Приемлим - так же, как и operator new.
PM MAIL   Вверх
mes
Дата 9.8.2008, 02:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(UnrealMan @  9.8.2008,  02:16 Найти цитируемый пост)
Приемлим - так же, как и operator new. 

вот и я о том же

Цитата(mes @  9.8.2008,  00:56 Найти цитируемый пост)
(но не советую использовать)


Добавлено через 51 секунду
в данном контексте нужен лишь для выделения памяти 


--------------------
PM MAIL WWW   Вверх
yep
Дата 9.8.2008, 02:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А вот ещё что интересует. Среди полей есть ещё статические массивы. В установочных методах делаю проверку на выход за пределы. Если выход есть, делаю исключение. Вот и подумал использовать вектор вместо массива чтобы не делать проверку, или есть что-то более подходящее? Как обычно поступают?
PM MAIL   Вверх
mes
Дата 9.8.2008, 02:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  9.8.2008,  02:26 Найти цитируемый пост)
Вот и подумал использовать вектор вместо массива чтобы не делать проверку, или есть что-то более подходящее? 

если неуверен, что попадаешь в  нужный диапазон в любом случае надо делать проверку, будь хоть обычный массив , хоть вектор.
Единственное что у вектора есть метод at, aналогичный [] , но возбуждает исключение при выходе за границы


--------------------
PM MAIL WWW   Вверх
yep
Дата 9.8.2008, 02:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А [] разве не возбуждает? У меня в VS2008 возбуждает
PM MAIL   Вверх
mes
Дата 9.8.2008, 02:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(yep @  9.8.2008,  02:36 Найти цитируемый пост)
А [] разве не возбуждает? У меня в VS2008 возбуждает 

[] : http://msdn.microsoft.com/en-us/library/f26e12y5(VS.80).aspx
at : http://msdn.microsoft.com/en-us/library/c6kkh778(VS.80).aspx


--------------------
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1788 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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