Вопрос по new ?!!!

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Plastic
Сообщения: 16
Зарегистрирован: 06 дек 2005, 10:41
Контактная информация:

Нужно создать процедуру в которой динамич. создаеться массив шрифтов.
Но - у класса шрифтов есть конструктор в который надо передовать данные:
*TxtFont = new CD3DFont(font_name, font_size, 0L);

Задача в том что мне надо создать не один элемент а _массив_.
то есть мне надо создать массив из n элементов...
пробую
*TxtFont = new[n] CD3DFont(font_name, font_size, 0L); - не работает.. :(

Просто массив без передачи параметров конструктору пробую:
*TxtFont = new[n] CD3DFont;
- выдает ошибку - 'CD3DFont' : no appropriate default constructor available.

Как правильно записать прцедуру? Или никак?? :(
Wizard
Сообщения: 9
Зарегистрирован: 10 дек 2005, 13:36
Откуда: Riga, Latvia

А ты не пробывал сначало задеклрирывать масив указателей, а потом в цыкле каждому отдельно вызвать конструктор.
Что нибуть вроде:
CD3DFont *TxtFont[5];

for (int i=0; i<5; i++) {
TxtFont[5] = new CD3DFont(font_name, font_size, 0L);
}

Результата не обещаю, но попробывать можно
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

В таком случае лучше использовать динамический массив указателей, тогда в него можно будет добавлять и удалять из него указатели по мере необходимости. что-то типа std::vector<CD3DFont*>.
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

*TxtFont = new[n] CD3DFont(font_name, font_size, 0L);
Правильно ругается - скобки не там поставил, надо так: new CD3DFont(font_name, font_size, 0L) [n]. А вообще WinMain прав, лучше использовать вектор.
Plastic
Сообщения: 16
Зарегистрирован: 06 дек 2005, 10:41
Контактная информация:

Eugie писал(а):
*TxtFont = new[n] CD3DFont(font_name, font_size, 0L)]

Правильно ругается - скобки не там поставил, надо так: new CD3DFont(font_name, font_size, 0L) [n]. А вообще WinMain прав, лучше использовать вектор.
При такой записи он вообще кричит что пропущена точка с запятой после скобок... :(
Пришлось решать проблему через одно место - менять класс CD3DFont (не мой!) чтобы ему не требовались параметры для конструктора...

это ж надо так в языке извратицца, чтобы без параметров - можно, а с параметрами - нельзя! :(
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

При такой записи он вообще кричит что пропущена точка с запятой после скобок...
Виноват :) "Массивная" форма new[] не допускает инициализацию, по крайней мере, если не определять пользовательскую функцию (глоб. или член класса) operator new[](). Да и в этом случае синтаксис инициализации будет несколько отличным, и семантика существенно меняется: инициализация происходит ДО вызова конструктора.

Вот пример:

Код: Выделить всё

class A
{
	int   m_n;
	bool  m_b;
	float m_f;
public:
	A() { /*nothing to do*/ }
  
  // initialization here - pseudoconstructor
	void Init(int n, bool b, float f) 
	{
		m_n = n;
		m_b = b;
		m_f = f;
	};

  void* operator new[](size_t size, int n, bool b, float f)
	{
		A* ptr = (A*)malloc(size);
		for (size_t i=0; i<size/sizeof(A); i++)
			ptr[i].Init(n, b, f);

		return ptr;
	}

	void operator delete[] (void* p)
	{
		free(p);
	}
	void print()
    {
		printf("%d\t%s\t%f\n", m_n, (m_b ? "true" : "false"), m_f);
	}
};

int main(int, char*)
{
	printf ("%d\n", sizeof(A));
	A a;
	A* pa = new(4,true,1) A [10];
	for (int i=0; i<10; i++)
		pa[i].print();

	delete [] pa;

	return 0;
}
atavin-ta
Сообщения: 585
Зарегистрирован: 30 янв 2009, 06:38

&quot писал(а):пробую
*TxtFont = new[n] CD3DFont(font_name, font_size, 0L); - не работает..
И не будет.
&quot писал(а):А ты не пробывал сначало задеклрирывать масив указателей, а потом в цыкле каждому отдельно вызвать конструктор.
Поддерживаю.
&quot писал(а):это ж надо так в языке извратицца, чтобы без параметров - можно, а с параметрами - нельзя!
Как раз, наоборот, полный изврат поддерживать оператор new для массивов с параметрами. Ведь каждый элемент массива индивидуален и может иницироваться со своими параметрами. Представь себе этот код и попробуй объяснить, каким образом разработчики стандарта смогли бы объяснить тебе, как именно они понимают передачу параметров экземплярам конструктора элементов динамического массива.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
&quot писал(а):Массивная" форма new[] не допускает инициализацию, по крайней мере, если не определять пользовательскую функцию (глоб. или член класса) operator new[](). Да и в этом случае синтаксис инициализации будет несколько отличным, и семантика существенно меняется: инициализация происходит ДО вызова конструктора.
Отсюда вывод - так делать не надо. Иницализация должна происходить не до вызова конструктора, а в конструкторе, а всё, что ведёт к нарушению этого правила - способы окнчательно привести прогу в негодное состояние. То есть, работать она может быть и будет, но попробуй через год понять, как именно.
Вопрос: "Почему вы все сионисты? Нельзя ли писать на чём то другом?".
Ответ: "Писать можно на чём угодно. Но зачем же так себя ограничивать? Пиши на С!".
Ответить