Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Daiser
Зарегистрирован: 28.01.2002 Сообщения: 44 Откуда: Челябинск
|
Добавлено: Пн Фев 03 2003 15:14 Заголовок сообщения: Знатокам C++ посвящяется! |
|
|
Есть класс CBigNumber. Для него перегружены операторы +,-,==,!=,= и т.д. Так же есть метод CBigNumber& CBigNumber::abs() { __GLOBAL__ = *this; __GLOBAL__.sign = 0; return __GLOBAL__; }, где __GLOBAL__ - глобальная переменная-класс CBigNumber.
Проблема в следующем: если делать, например, if(a.abs() == b.abs()), то естественно __GLOBAL__ сравнивается с __GLOBAL__ и в результате всегда получается 1 (TRUE). Вопрос: как это поправить? Только есть одно НО: в классе используется динамическое выделения памяти, т.е. после выхода из функции деструктор вызывать нельзя. |
|
Вернуться к началу |
|
|
Борис Гость
|
Добавлено: Пн Фев 03 2003 18:02 Заголовок сообщения: Re: Знатокам C++ посвящяется! |
|
|
Введение -------- Когда имеется предложение if(a.abs() == b.abs()), где a.abs() и b.abs() умещаются в регистры процессора, то есть обычное сравнение if(abs(int) == abs(int)), то после сравнения операнды уничтожаются автоматически следующей процессорной инструкцией. А в твоем случае операнды находятся в основной памяти, и поэтому их нужно уничтожать в зависимости от потребностей программы: если a.abs() (b.abs()) нужно только для сравнения, то после операции сравнения их нужно уничтожить, а если их a.abs() (b.abs()) нужно заносить в другую переменную, то их надо сохранить.
Глава 1 ------- Реализация этих противоположных требований в том, чтобы сообщить компилятору, когда нужно уничтожать a.abs() (b.abs()), а когда сохранять. Тут можно придумать много алгоритмов. Самый простой (но не самый эффективный) пример следующий: определить функции (записываю условно) - CBigNumber& CBigNumber::abs() для случая, когда уничтожать a.abs() (b.abs()) не нужно; - struct CBigNumberToDel {CBigNumber num;}; CBigNumberToDel& abs(CBigNumber&) для случая, когда уничтожать a.abs() (b.abs()) не нужно.
Первая возвращает ссылку на *this, вторая _создает_ копию и возвращает ссылку на нее.
Соответственно определить функции: operator==(CBigNumberToDel&, CBigNumberToDel&); operator==(CBigNumberToDel&, CBigNumber&); operator==(CBigNumber&б CBigNumberToDel&); operator==(CBigNumber&, CBigNumber&);
В первой, второй и третьей функциях функция уничтожает операнд CBigNumberToDel&. |
|
Вернуться к началу |
|
|
Борис Гость
|
Добавлено: Пн Фев 03 2003 18:11 Заголовок сообщения: Мои извинения, опечатка. Последние строки абзаца 1 главы 1 читать так: (+) |
|
|
- CBigNumber& CBigNumber::abs() для случая, когда уничтожать a.abs() (b.abs()) НЕ НУЖНО; - struct CBigNumberToDel {CBigNumber num;}; CBigNumberToDel& abs(CBigNumber&) для случая, когда a.abs() (b.abs()) НУЖНО уничтожить. |
|
Вернуться к началу |
|
|
Борис Гость
|
Добавлено: Пн Фев 03 2003 18:19 Заголовок сообщения: Любопытно, что за проект продвигаешь? Вообще говоря, есть библиотека Integer в проекте GNU. Там как раз большие целые. (-) |
|
|
- |
|
Вернуться к началу |
|
|
Юрий_Алексеевич Гость
|
Добавлено: Пн Фев 03 2003 19:21 Заголовок сообщения: Re: Знатокам C++ посвящяется! |
|
|
А как насчёт зачистки задним числом? Возвращать CBigNumber, а не CBigNumber&. Кажется, компилятор может заставить программу вызвать по деструктору для кождого объекта. Если это не так, то CBigNumber** CBN_all; unsigned very-very long CBN_all_qty; void main() { do_someshing(); while(CBN_all_qty) // деструктор уменьшает это на 1 (*CBN_all) -> ~CBigNumber(); } Ну или вроде того. |
|
Вернуться к началу |
|
|
|