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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 31.10.2009, 23:20   #1
girkoff
Пользователь
 
Регистрация: 07.11.2008
Сообщений: 71
По умолчанию Помогите с конструктором

У меня такая проблема, у каждого return компилятор мне выдаёт ошибку, что ретурн должен возвращать значение, но когда ставлю 0 он мне пишет совсем обратное, что ретурн не должен возвращать значение. Я не могу понять, почему не проверяет файл на открытие ведб без конструктора работало всё как часы.
Вот мой класс:
Код:
class people {
        public:
FILE *file1,*file2,*out;
people()
{
char f1[100],f2[100],f3[100];
printf("VVedite put' k file1: \n");
scanf("%s",f1);
printf("VVedite put' k file2: \n");
scanf("%s",f2);
printf("VVedite put' k out:  \n");
scanf("%s",out);
if ((file1=fopen("f1","r"))==0)
{
printf("oshibka otkritia file1!!!");
return ;
}
if ((file2=fopen("f2","r"))==0)
{
printf("osibka otkritia file1!!!");
return ;
}
if ((out=fopen("out","a+b"))==0)
{
printf("oshibka otkritia out!!!");
return ;
}
}
Если долго мучаться, что нибудь получится!!!
girkoff вне форума Ответить с цитированием
Старый 31.10.2009, 23:30   #2
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Конструктор создан для инициализации внутренних свойств класса и не может возвращать значения. поубирайте return-ы и будет работать. Обработку исключительных ситуаций можете вынести за пределы класса, или использовать throw в конструкторе
netrino вне форума Ответить с цитированием
Старый 31.10.2009, 23:39   #3
girkoff
Пользователь
 
Регистрация: 07.11.2008
Сообщений: 71
По умолчанию

а что делает throw в инете полазал, не понял!!!
Если долго мучаться, что нибудь получится!!!
girkoff вне форума Ответить с цитированием
Старый 31.10.2009, 23:54   #4
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

throw бросает исключение, которое можно перехватить и обработать. Пример:
Код:
#include <iostream>

int divide(int a, int b)
{
    if( b == 0 )
        throw "Divide by zero";
    else
        return a/b;
}

int main()
{
    int z;

    try {
        z = divide(434, 0);
    }
    catch(char* Error) {
        std::cout << Error << std::endl;
    }

    return 0;
}
Вместо указателя на строку можно бросать экземпляр класса, в котором будет содержаться расширенная информация об ошибке, или же для специализации исключения.
netrino вне форума Ответить с цитированием
Старый 01.11.2009, 00:55   #5
girkoff
Пользователь
 
Регистрация: 07.11.2008
Сообщений: 71
По умолчанию

если не сложно можно с пояснениями, я не могу понять для чего нужны исключения
Если долго мучаться, что нибудь получится!!!
girkoff вне форума Ответить с цитированием
Старый 01.11.2009, 01:04   #6
nazavrik
Форумчанин
 
Аватар для nazavrik
 
Регистрация: 01.09.2008
Сообщений: 178
По умолчанию

Хотябы для того, чтобы приложение при возникновении ошибки/исключения не вылетало с потерей всех данных, а выводило предупреждение об ошибке и завершалось.
Быть радикальным - значит понять вещь в её корне. К.Маркс
nazavrik вне форума Ответить с цитированием
Старый 01.11.2009, 01:11   #7
Hacker19_90
Delphi Warrior
Старожил
 
Аватар для Hacker19_90
 
Регистрация: 15.08.2008
Сообщений: 2,502
По умолчанию

Суть этого понятия в том, что функция, которая обнаружила ошибку и не может справиться с нею,
запускает особую ситуацию, рассчитывая, что устранить проблему можно в той функции, которая прямо
или опосредованно вызывала первую. Если функция рассчитана на обработку ошибок некоторого вида,
она может указать это явно, как готовность перехватить данную особую ситуацию.
Рассмотрим в качестве примера как для класса Vector можно представлять и обрабатывать особые
ситуации, вызванные выходом за границу массива:
class Vector {
int* p;
int sz;
public:
class Range { }; // класс для особой ситуации
int& operator[](int i);
// ...
};

Предполагается, что объекты класса Range будут использоваться как особые ситуации, и запускать их можно так:
int& Vector:perator[](int i)
{
if (0<=i && i<sz) return p[i];
throw Range();
}
Если в функции предусмотрена реакция на ошибку недопустимого значения индекса, то ту часть
функции, в которой эти ошибки будут перехватываться, надо поместить в оператор try. В нем должен
быть и обработчик особой ситуации:
void f(Vector& v)
{
// ...
try {
do_something(v); // содержательная часть, работающая с v
}
catch (Vector::Range) { // обработчик особой ситуации Vector::Range
// если do_something() завершится неудачно,
// нужно как-то среагировать на это
// сюда мы попадем только в том случае, когда
// вызов do_something() приведет к вызову Vector:perator[]()
// из-за недопустимого значения индекса
}
// ...
}
Обработчиком особой ситуации называется конструкция
catch ( /* ... */ ) {
// ...
}
Ее можно использовать только сразу после блока, начинающегося служебным словом try, или сразу
после другого обработчика особой ситуации. Служебным является и слово catch. После него идет в
скобках описание, которое используется аналогично описанию формальных параметров функции, а
именно, в нем задается тип объектов, на которые рассчитан обработчик, и, возможно, имена
параметров (см. $$9.3). Если в do_something() или в любой вызванной из нее функции произойдет
ошибка индекса (на любом объекте Vector), то обработчик перехватит особую ситуацию и будет
выполняться часть, обрабатывающая ошибку. Например, определения следующих функций приведут к
запуску обработчика в f():
void do_something()
{
// ...
crash(v);
// ...
}

void crash(Vector& v)
{
v[v.size()+10]; // искусственно вызываем ошибку индекса
}
Mess with the best, die like the rest. (с) Hackers
Лабораторные, курсовые на Delphi\Pascal\C++
ya.flex-freelance@yandex.ru Icq - 636-954-303
Hacker19_90 вне форума Ответить с цитированием
Старый 01.11.2009, 01:14   #8
Hacker19_90
Delphi Warrior
Старожил
 
Аватар для Hacker19_90
 
Регистрация: 15.08.2008
Сообщений: 2,502
По умолчанию

А ещё лучше почитай Страуструпа!!!!
Mess with the best, die like the rest. (с) Hackers
Лабораторные, курсовые на Delphi\Pascal\C++
ya.flex-freelance@yandex.ru Icq - 636-954-303
Hacker19_90 вне форума Ответить с цитированием
Старый 01.11.2009, 01:16   #9
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Исключения нужны для ситуаций, которые вызываемая функция не в состоянии разрулить, или когда обработку этой ситуации нужно возложить на пользователя. В показанном мною примере функция бросает исключение, если в качестве делителя выступает 0, это исключение отлавливается в пользовательском коде и соответствующим образом обрабатывается(выводится сообщение об ошибке). Как я говорил раннее можно использовать классы для специализации исключений(можно дать какому-нибудь виду исключения определённое имя и потом отлавливать именно его). Базовым классом для таких специализированных исключений, как правило, является std::exception из заголовочника exception
Вот пример с комментариями, немного надуманный, но всё же :
Код:
// Предположим, что нам необходима функция, которая делит одно число на другое
// При этом результат обязательно должен быть положительным

#include <iostream>
#include <exception> // Тут содержится базовый класс exception

class ZeroDivide : public std::exception {
	// Реализуем класс-исключение, который будет бросаться при делении на ноль
public:
	ZeroDivide(const char* Msg) : std::exception(Msg)
	{ } // Вызываем конструктор родителя, чтобы сохранить сообщение об ошибке
};

class NegativeResult : public std::exception {
	// Класс-исключение, который будет бросаться, если результат отрицательный
public:
	NegativeResult(const char* Msg, int Res) : std::exception(Msg)
	{ Result = Res; } // Вызываем конструктор родителя и инициализируем собственные данные класса

	int getResult() const // Описание методов
	{
		return Result;
	}
private:
	int Result;
};

int divide(int a, int b)
{
    if( b == 0 )
        throw ZeroDivide("Divide by zero"); // Если делитель 0 - бросаем исключение деления на 0
	else if( a/b < 0 ) // Если результат деления отрицательный - бросаем исключение отрицательного результата.
		throw NegativeResult("Result is negative.", a/b); 
    else
        return a/b; // В ином случае нормальное завершение функции
}

int main()
{
	int z;
	int x, y;

	std::cout << "Enter x: ";
	std::cin  >> x;
	std::cout << "Enter y: ";
	std::cin  >> y;

	try { // Блок, в котором перехватываются исключения
		z = divide(x, y);
	}
	catch(ZeroDivide e) { // Перехват исключения типа ZeroDivide
		std::cout << e.what() << std::endl; // Выводим сообщение об ошибке
		// Метод what() определён в классе exception и возвращает указатель на сообщение, переданное в конструктор
		system("pause");
		return -1; // И выходим из программы после нажатия клавиши
	}
	catch(NegativeResult e) { // Перехват исключения типа NegativeResult
		std::cout << e.what() << std::endl; // Выводим сообщение об ошибке
		z = -e.getResult(); // Исправляем результат так, что он подходит под условие и продолжаем выполнение
	}

	std::cout << "Z = " << z << std::endl;

	system("pause");

	return 0;
}
...

Опередили ))
netrino вне форума Ответить с цитированием
Старый 01.11.2009, 15:40   #10
girkoff
Пользователь
 
Регистрация: 07.11.2008
Сообщений: 71
По умолчанию

всем спосибо, начал въезжать, и скачал книгу Страуструпа, теперрь засяду за обучением!!!
Если долго мучаться, что нибудь получится!!!
girkoff вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как проверить создан ли класс конструктором? Вадим Буренков Общие вопросы Delphi 10 01.07.2009 22:47
массив объектов с конструктором копии pu4koff Общие вопросы C/C++ 6 18.06.2008 17:33