Форум программистов, компьютерный форум CyberForum.ru

Вопрос по исключениям в шаблонах классов - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.70
kniazik
0 / 0 / 0
Регистрация: 21.12.2009
Сообщений: 25
10.06.2011, 20:56     Вопрос по исключениям в шаблонах классов #1
Кто подскажет как реализовать исключения в следующей задаче:

Создать шаблонный класс, в котором создать одномерный массив и найти сумму элементов от n до m.

Не могу понять как это сделать, кто может подсказать - буду благодарен, заранее СПАСИБО.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
10.06.2011, 21:02     Вопрос по исключениям в шаблонах классов #2
Например, при реализации конструктора, который собственно и создает массив, надо проверять, чтобы размер массива был больше 0.
А метод, который суммирует, наверное, должен проверять, чтобы n < m < size
При нарушении подобных условий и надо генерить исключения.
kniazik
0 / 0 / 0
Регистрация: 21.12.2009
Сообщений: 25
10.06.2011, 21:17  [ТС]     Вопрос по исключениям в шаблонах классов #3
Спасибо, но можно ли пример, хотя б одного исключения?
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
10.06.2011, 22:09     Вопрос по исключениям в шаблонах классов #4
А ты книжек не открывал?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{    try { throw 1;                           // генерация исключения
        }
    catch(unsigned int)
        { cout << "unsigned integer" << endl;
        }
    catch(int)                                // перехватывается здесь
        { cout << "integer" << endl;
        }
    catch(double)
        { cout << "double" << endl;
        }
    return 0;
}
На экране появится слово integer, так как константа 1 по умолчанию имеет тип int.
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
10.06.2011, 23:01     Вопрос по исключениям в шаблонах классов #5
ValeryLaptev, исключения в конструкторе - это херово.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
10.06.2011, 23:04     Вопрос по исключениям в шаблонах классов #6
Цитата Сообщение от OstapBender Посмотреть сообщение
ValeryLaptev, исключения в конструкторе - это херово.
А куда деваться, если класс динамически запрашивает, например, память, а new выдает bad_alloc?
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
10.06.2011, 23:11     Вопрос по исключениям в шаблонах классов #7
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
А куда деваться, если класс динамически запрашивает, например, память, а new выдает bad_alloc?
а черт его знает.
ну по крайней мере можно обрабатывать их прямо в конструкторе, но никак не вне его, думаю.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
10.06.2011, 23:20     Вопрос по исключениям в шаблонах классов #8
Не... Исключения и были придумано ВО МНОГОМ из-за конструкторов. Ведь любая функция может вернуть результат. А конструктор - НЕТ! Как сообщить об аварии и невозможности создать объект?
Более того, придумали специальную конструкцию try-block-function - чтобы контролировать список инициализации конструктора.
Вторая причина - перегруженные операции. У них тоже лишних параметров не находится - нельзя изменять количество аргументов при перегрузке. Опять же - как сообщать об аварии? Исключением!
train-killer
0 / 0 / 0
Регистрация: 07.06.2011
Сообщений: 3
10.06.2011, 23:25     Вопрос по исключениям в шаблонах классов #9
Цитата Сообщение от OstapBender Посмотреть сообщение
можно обрабатывать их прямо в конструкторе, но никак не вне его, думаю.
Обработка ошибок вне конструктора необходима, что бы сообщить коду, вызывающему конструктор, что создание объекта провалилось.
По моему, это как раз и была одна из причин, по которым в С++ включили конструкцию try...catch.


Упс! Опоздал с ответом ))
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
10.06.2011, 23:31     Вопрос по исключениям в шаблонах классов #10
Цитата Сообщение от OstapBender Посмотреть сообщение
а черт его знает.
ну по крайней мере можно обрабатывать их прямо в конструкторе, но никак не вне его, думаю.
Это касается, в первую очередь, деструкторов. Почитайте Герба Саттера - он хорошо объясняет, почему. Можно и у Скотта Мейерса найти мысли по этому вопросу.
А для конструкторов нормально генерить исключения в случае аварии.
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
10.06.2011, 23:37     Вопрос по исключениям в шаблонах классов #11
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Почитайте Герба Саттера - он хорошо объясняет, почему.
хорошо, добавлю в длинный список того что надо прочитать)

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
А для конструкторов нормально генерить исключения в случае аварии.
даже не знаю...
если создание объекта на середине прервалось, и исключение перехвачено вне конструктора, то единственный способ уйти без потерь это немедленно завершить программу, или как иначе?
ну а если нам не надо завершать программу.. а в конце стоит вожделенный delete obj;
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
10.06.2011, 23:41     Вопрос по исключениям в шаблонах классов #12
OstapBender, не обязательно. Если вы внимательно почитаете С++, то обнаружите, что, например, при вызове new в конструкторе - утечек не происходит...
Или например, конструктор не открыл файл. Это решать должна та функция, которая создавала объект, а он - не создался.
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
10.06.2011, 23:50     Вопрос по исключениям в шаблонах классов #13
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Если вы внимательно почитаете С++
какой именно?))

вот сваял 2 примера как я это понимаю:

1 - исключение обрабатывается в конструкторе - тут всё вроде-бы неплохо
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class a {
    int *i;
 
public:
    a(int v) {
 
        try {
        if (v<=0) throw 1;
 
        i = new int[v];
 
        } catch(int) {
            i=0;
        }
        
        std::cout << "ctor ok\n";
 
    }
    ~a() {
        if (i)
        delete[] i; 
        std::cout << "dtor ok\n";
    }
 
};
 
 
 
int main()
{
    a* ob;
 
    try {
    ob = new a(-5);
    } catch(int) {
        std::cout << "Bad alloc\n";
    }
 
    delete ob;
 
 
 
 
    getchar();
    return 0;
}
2- выбрасываю в мейн, получаю критическую ошибку
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class a {
    int *i;
 
public:
    a(int v) {
 
        try {
        if (v<=0) throw 1;
 
        i = new int[v];
 
        } catch(int) {
            throw;
        }
        
        std::cout << "ctor ok\n";
 
    }
    ~a() {
        if (i)
        delete[] i; 
        std::cout << "dtor ok\n";
    }
 
};
 
 
 
 
 
int main()
{
    a* ob;
 
    try {
    ob = new a(-5);
    } catch(int) {
        std::cout << "Bad alloc\n";
    }
 
    delete ob;
 
 
 
 
    getchar();
    return 0;
}

если вы придете ваш пример я буду вам благодарен.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
11.06.2011, 00:00     Вопрос по исключениям в шаблонах классов #14
Все проще:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class a {
        int *i;
        int size;
public:
        a(int v) 
        { if (v<=0) throw 1;
          i = new int[v];
          size = v;
          std::cout << "ctor ok\n";
        }
        int size() { return size; }
        ~a() 
        {  delete[] i; 
           std::cout << "dtor ok\n";
        }
};
 
 
int main()
{
    try {
          a ob(-5);
        } catch(int) {
                std::cout << "Bad alloc\n";
        }
        system("pause");
                return 0;
}
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
11.06.2011, 00:03     Вопрос по исключениям в шаблонах классов #15
хехехе) ну так ваш ob создается и существует только в блоке try...
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
11.06.2011, 00:12     Вопрос по исключениям в шаблонах классов #16
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Вот вам инфа про динамические объекты:

Классы (non-Pod типы)
Любой класс, не удовлетворяющий перечисленным выше условиям , является non-POD типом. Стандарт определяет, что создание динамического non-POD объекта операцией new выполняется в два этапа:
1. Для объекта выделяется необходимое количество свободной памяти.
2. Вызывается конструктор, чтобы проинициализировать выделенную память.

Время жизни динамических non-POD объектов начинается только с момента окончания работы конструктора. Первый шаг для одиночного объекта выполняется функцией выделения памяти operator new(), и функцией operator new[]() — для массива объектов. В стандарте [1 3.7.3, 18.4] эти функции определены так:
C++
1
2
void *operator new(std::size_t size) throw(std::bad_alloc);
void *operator new[](std::size_t size) throw(std::bad_alloc);
Отметим, что при невозможности выделить память конструктор не вызывается. Более того, пункт стандарта 5.3.4/17 гласит, что в случае возникновения исключения во время инициализации объекта сначала выполняется возврат выделенной памяти, а затем начинается обработка исключения. Таким образом, механизм new/delete еще и значительно более надежен и безопасен по сравнению с механизмом malloc()/free().

Уничтожение динамического объекта тоже выполняется в два шага: сначала вызывается деструктор, а затем функция возврата памяти. Время жизни динамического объекта заканчивается, когда начинается выполнение кода деструктора. Функции возврата памяти определены в стандарте там же, где и функции выделения памяти, и имеют следующие прототипы:
C++
1
2
void operator delete (void *) throw();
void operator delete [](void *) throw();
Как и показанное выше создание динамических POD-объектов, динамический объект произвольного класса можно создать без инициализации.
C++
1
2
Type *p1 = new Type;                
Type *p2 = new Type();
При наличии в классе определенного конструктора без аргументов в данном случае после выделения памяти вызывается именно он. Кроме того, мы можем инициализировать динамические объекты (аналогично объектам встроенных типов), если в классе определен конструктор инициализации.

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

Создание динамических объектов-констант ничем не отличается от создания динамических констант встроенных типов. Конечно, даже динамически создаваемую константу требуется инициализировать (для этого в классе должен быть определен конструктор инициализации), однако и Visual C++.NET 2003, и C++ Builder 6 «пропускают» отсутствие инициализации. Например, без всяких сообщений транслируется такое объявление
C++
1
const Type *p1 = new const Type;
Естественно, в этом случае во время выполнения вызывается конструктор без аргументов.

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

Добавлено через 2 минуты
Цитата Сообщение от OstapBender Посмотреть сообщение
хехехе) ну так ваш ob создается и существует только в блоке try...
Вот тебе и с динамическим:
C++
1
2
3
4
5
6
7
8
9
10
11
int main()
{   a *pa;
    try {
          a ob(5);
          pa = new a(-5);
        } catch(int) {
                std::cout << "Bad alloc\n";
        }
        system("pause");
                return 0;
}
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
11.06.2011, 00:20     Вопрос по исключениям в шаблонах классов #17
спасибо большинство из этого знал, а вот этого не знал
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Отметим, что при невозможности выделить память конструктор не вызывается. Более того, пункт стандарта 5.3.4/17 гласит, что в случае возникновения исключения во время инициализации объекта сначала выполняется возврат выделенной памяти, а затем начинается обработка исключения. Таким образом, механизм new/delete еще и значительно более надежен и безопасен по сравнению с механизмом malloc()/free().

но где в примере в конце
delete pa; ??????
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
11.06.2011, 08:19     Вопрос по исключениям в шаблонах классов #18
Цитата Сообщение от OstapBender Посмотреть сообщение
спасибо большинство из этого знал, а вот этого не знал



но где в примере в конце
delete pa; ??????
Программка маленькая. При завершении система обратно все вернет. Нету вложенности, чтоб указатели терялись.
Хотя я просто забыл... )
kniazik
0 / 0 / 0
Регистрация: 21.12.2009
Сообщений: 25
12.06.2011, 14:44  [ТС]     Вопрос по исключениям в шаблонах классов #19
Всем большое спасибо, но как реализовать исключения в моей задаче?

Вот - именно в моей? В конструкторе ?

И как лучше - может быть создать класс исключений? Тогда какой ? как учитывать хотя бы самое простое - N>M. В книге очень туго все написано. СПАСИБО

Добавлено через 18 часов 21 минуту
Ребята, помогите решить .. ну не шарю я в этом.

Добавлено через 1 час 7 минут
может кого материально заинтересует, сегодня точно нужно решить
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.06.2011, 14:56     Вопрос по исключениям в шаблонах классов
Еще ссылки по теме:

C++ Подстановка вычисляемого типа в шаблонах
Стек на шаблонах - оцените реализацию C++
C++ Класс на шаблонах, менять аргументы шаблона

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
OstapBender
 Аватар для OstapBender
581 / 519 / 35
Регистрация: 22.03.2011
Сообщений: 1,585
12.06.2011, 14:56     Вопрос по исключениям в шаблонах классов #20
пишу не из дома в блокноте
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
template <class T>
class Array1D {
 
T* data;
int sz; 
 
public:
 
Array1D():data(0),n(0) {}
Array1D(int s):n(s) { data = new T[n]; }
~Array1D() { delete[] data; }
T sumNM(int n, int m) {
T sum=0;
try {
if (n>m || m>sz || n<0) throw -1;
 
for (int i=n; i<m; i++)
sum+=data[i];
 
} catch(int e) {
return e;
}
 
return sum;
 
 
 
}
 
 
};
 
 
int main()
{
Array1D<int> arr(10);
int sum;
 
try {
 
sum=arr.sumNM(-4,5);
 
if (sum==-1) throw 0;
std::cout << "sum n-m = " << sum << '\n';
 
} catch(int) {
std::cout << "bad sum\n";
}
 
 
 
 
return 0;
 
}
Yandex
Объявления
12.06.2011, 14:56     Вопрос по исключениям в шаблонах классов
Ответ Создать тему
Опции темы

Текущее время: 03:02. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru