Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.12.2014, 10:41   #1
Gdasar
Пользователь
 
Регистрация: 18.02.2013
Сообщений: 60
Вопрос Инициализация объектов класса

Есть 3 класса : один - абстрактный,базовый(Item), 2 - производных(Book,Magazine).
Пример конструктора базового класса Item
Код:
Item(int _invN, string _name)
{
	this->invN  = _invN;	//инициализация инв номера
	this->name = _name;	//инициализация имени
	this->taken = false;	//предмет изначально не взят
}
Пример конструктора с параметрами класса Book(Magazine практически такой же) с четырьмя параметрами с вызовом базового конструктора:
Код:
Book(int _invN, string _name, string _author, int _year) : Item(_invN, _name)
{
	this->author = _author;		//инициализация автора
	this->year = _year;		//инициализация года
}
Код:
int _tmain(int argc, _TCHAR* argv[])
{
	int count;
	Item *item;
	/*Выводим подсказки*/
	cout << "Vvedi kol-vo predmetov : " << endl;
	cin >> count; // количествово предметов
	cout << "=============================" << endl;
	cout << "Kniga : 1" << endl;
	cout << "Zhurnal : 2" << endl;
	cout << "Zakonchit? : 0" << endl;
	cout << "=============================" << endl;
	char x;		// объявляем символьную переменную x
	x = getchar();	// записываем в x символ, принимаемый с клавиатуры
	switch (x)
	{
	case '1':  item = new Book[count]; break;  // создаем динамический массив книг
	case '2': item = new Magazine[count]; break; // создаем динамический массив журналов
	case '0': exit(0);  // выходим из программы
	default:  item = NULL; cout << "Error" << endl; break;// выводим ошибку
	}
	cout << "Vvedite informaciy o predmetah" << endl;
/*не знаю как дальше
          	for (int i = 0; i < count; i++)
	{
	}
*/
	_getch();
	return 0;
}
Мы запрашиваем у пользователя, сколько нужно объектов, и какого типа они должны быть Book или Magazine. Далее ведется заполнение объектов(инициализация).

Вопрос: как создать массив объектов в зависимости от начальных данных, с дальнейшей инициализацией(используя конструктор с параметрами).
С одним объектом все понятно:
Код:
Item *item2 = new Magazine(1,"rr","yy",2014);
item2->Show();
Item *item1 = new Book(1,"rr","yy",2014);
item1->Show();
А вот как с массивом я не знаю.
Помогите, пожалуйста.
Gdasar вне форума Ответить с цитированием
Старый 09.12.2014, 11:08   #2
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Никак не сделать то, что хочется в данном виде.
Вообще я подозреваю, что неправильно задача решается. Нужно массив, в который заносятся и книги и журналы, а не только книги или журналы.
Тут нужен не массив объектов, а массив указателей на базовый класс:
Item **item;
item = new Item*[count];
потом запрашивать у пользователя данные во временные переменные. Когда пользователь по текущему элементу всё ввёл, уже создавать объект
item[n] = new Book(...);
pu4koff вне форума Ответить с цитированием
Старый 09.12.2014, 11:16   #3
Gdasar
Пользователь
 
Регистрация: 18.02.2013
Сообщений: 60
По умолчанию

Задание:
Цитата:
Создать массив предметов, создавать объекты с использованием меню, в зависимости от введённого значения (например, 1 – книга, 2 – журнал, 0 – закончить создавать объекты). Вывести информацию обо всех объектах, используя виртуальный метод Show().
...

Последний раз редактировалось Stilet; 10.12.2014 в 18:57.
Gdasar вне форума Ответить с цитированием
Старый 09.12.2014, 21:58   #4
Gdasar
Пользователь
 
Регистрация: 18.02.2013
Сообщений: 60
По умолчанию

Делаю так:
Код:
void Show_Info(Item **item, int count)
{
	cout << "Predmeti :" << endl;
	for (int i = 0; i < count; i++)
	{
		item[i]->Show();
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	int count;
	Item **item;
	int n, y , iter = 0;
	string aut, off;
	/*Выводим подсказки*/
	cout << "Vvedi kol-vo predmetov : " << endl;
	cin >> count; // количествово предметов
	cout << "COUNT = " << count << endl;
	item = new Item*[count];
	cout << "=============================" << endl;
	cout << "Kniga : 1" << endl;
	cout << "Zhurnal : 2" << endl;
	cout << "Zakonchit? : 0" << endl;
	cout << "=============================" << endl;
	char x;		// объявляем символьную переменную x
	for (int i = 0; i < count; i++)
	{
		x = getchar();	// записываем в x символ, принимаемый с клавиатуры
		cout << "X = " << x << endl;
		cout << "Vvedite informaciy o predmete № " << (i+1) << endl;
		cin >> n;
		cin >> aut;
		cin >> off;
		cin >> y;
		switch (x)
		{
		case '1':  item[i] = new Book(n, aut, off, y); iter++; break;  // создаем динамический массив книг
		case '2': item[i] = new Magazine(n, aut, off, y); iter++; break; // создаем динамический массив журналов
		case '0': Show_Info(item, iter); break;  // закончить ввод
		default:  item = NULL; cout << "Error" << endl; break;// выводим ошибку
		}
	}
	_getch();
	return 0;
}
Но вот не задача: почему то программа не желает считывать X.
Изображения
Тип файла: jpg ппппппрар.jpg (19.7 Кб, 122 просмотров)
Gdasar вне форума Ответить с цитированием
Старый 10.12.2014, 07:57   #5
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

лучше заменить x = getchar(); на cin >> x
там свои нюансы с буферами. нужно либо перед getchar очищать буфер, чтобы запрос был именно с клавиатуры, а не какой-то хлам от предыдущих вводов с клавиатуры. Если используете cin для ввода, то везде его и используйте, так меньше подобных проблем будет.
pu4koff вне форума Ответить с цитированием
Старый 10.12.2014, 17:59   #6
Gdasar
Пользователь
 
Регистрация: 18.02.2013
Сообщений: 60
По умолчанию

pu4koff, спасибо. Но не могли бы Вы еще мне помочь - продумать логику.
Вот,смотрите:
Код:
		switch (x)
		{
		case '1':  item[i] = new Book(n, aut, off, y); iter++; break;  // создаем динамический массив книг
		case '2': item[i] = new Magazine(n, aut, off, y); iter++; break; // создаем динамический массив журналов
		case '0':  // как закончить ввод?
		default:  item = NULL; cout << "Error" << endl; break;// выводим ошибку
		}
Например, пользователь ввел 0, что значит ввод данных завершен, и их нужно вывести пользователю обратно.
Собственно сам вопрос : как мне прервать сам цикл for?
Gdasar вне форума Ответить с цитированием
Старый 10.12.2014, 18:48   #7
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Я бы проверку на ноль сделал до свича. Сразу после ввода х. А то сейчас получается, что пользователь вводит 0, говоря, что ему больше ничего не надо, а приходится сначала вбивать данные, которые потом никуда не запишутся.
Заодно в if можно спокойно написать break, который закончит цикл, а не свич.
Вывод же данных я бы вынес за цикл for, а то сейчас пользователь увидит что ввёл только при условии, что обманул и решил закончить ввод до того, как вбил указанное в самом начале число элементов.
Как-то так, в общем:
Код:
...
for (int i = 0; i < count; i++)
	{
		do
		// лучше вообще зациклить ввод x, чтобы не думать что делать
		// при вводе x = 10, а в текущей ситуации при выводе нарвёмся
		// на NULL объекты посреди массива и посыпятся исключения
		{
			cin >> x;	// записываем в x символ, принимаемый с клавиатуры
			if (x < '0' || x > '2') // если неправильный х, то выведем какую-нибудь подсказку тупому вводителю, который не знает цифры от 0 до 2
				cout << "Какой-то неправильный x. Нужно 0, 1 или 2"
			else // Если справился с вводом, то молодец
				cout << "X = " << x << endl;
		}
		while (x < '0' || x > '2'); // тут дублируется проверка для зацикливания ввода, что не хорошо, но мне лень думать как от этого уйти
		if (x == '0') // если пользователь решил, что с него хватит
		{
			count = i + 1; // меняем число элементов на "реальное", а не обещанное ранее
			break; // завершаем цикл нафиг
		}
		// тут я ничего не менял
		cout << "Vvedite informaciy o predmete № " << (i+1) << endl;
		cin >> n;
		cin >> aut;
		cin >> off;
		cin >> y;
		// тут уже можно подправить
		switch (x)
		{
		case '1':  item[i] = new Book(n, aut, off, y); iter++; break;  // создаем динамический массив книг
		case '2': item[i] = new Magazine(n, aut, off, y); iter++; break; // создаем динамический массив журналов
		default:  item[i] = NULL; break;// сюда в принципе теперь не попадём, но пусть будет, 
//чтобы компилятор радовался, что item всегда инициализирован, хотя ему это и не надо. в общем, можно выкинуть за ненадобностью :)
		}
	}
	// Сюда попадаем когда завершили вводить всю инфу.
	// Вот и пусть пользователь смотрит на результат своих трудов
	Show_Info(item, count); // это выполнится и если на полпути ввели 0 и есть вбили обещанное число элементов
	_getch(); // с этим опять же аккуратнее, а то символ может уже какой-нибудь в буфере быть и пользователь ничего не увидит
	return 0;

Последний раз редактировалось Stilet; 10.12.2014 в 18:58.
pu4koff вне форума Ответить с цитированием
Старый 10.12.2014, 19:49   #8
Gdasar
Пользователь
 
Регистрация: 18.02.2013
Сообщений: 60
По умолчанию

pu4koff, спасибо.
Код:
int _tmain(int argc, _TCHAR* argv[])
{
	int count;
	Item **item;
	int n, y , iter = 0;
	string aut, off;
	/*Выводим подсказки*/
	cout << "Vvedi kol-vo predmetov : " << endl;
	cin >> count; // количествово предметов
	item = new Item*[count];
	cout << "=============================" << endl;
	cout << "Kniga : 1" << endl;
	cout << "Zhurnal : 2" << endl;
	cout << "Zakonchit? : 0" << endl;
	cout << "=============================" << endl;
	char x;		// объявляем символьную переменную x
	for (int i = 0; i < count; i++)
	{
		cout << "Vvedi tip rredmeta" << endl;
		cin >> x;	// записываем в x символ, принимаемый с клавиатуры
		if (x == '0')
			break;
		cout << "Vvedite informaciy o predmete # " << (i + 1) << endl;
		cin >> n;
		cin >> aut;
		cin >> off;
		cin >> y;
		switch (x)
		{
		case '1':  item[i] = new Book(n, aut, off, y); iter++; break;  // создаем динамический массив книг
		case '2': item[i] = new Magazine(n, aut, off, y); iter++; break; // создаем динамический массив журналов
		default:  item = NULL; cout << "Error" << endl; break;// выводим ошибку
		}
	}
		Show_Info(item, iter);
	_getch();
	delete[] item;
	return 0;
}
Gdasar вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не понятная проблема, адрес переменной класса у 2 объектов класса одинаков Soeth Общие вопросы C/C++ 8 06.11.2013 05:10
[visual c++] инициализация статических членов класса densvr Помощь студентам 0 10.02.2013 18:24
Инициализация элемента массива класса VmanMaslov Общие вопросы C/C++ 10 15.02.2012 20:57
Инициализация матрицы методом класса Jugger Общие вопросы C/C++ 4 20.10.2011 20:43
с++ инициализация статических елементов класса p_alex Помощь студентам 5 25.10.2009 16:52