Цитата(Iron Bug @ 31.3.2010, 18:30)
Цитата(Tonal @ 31.3.2010, 9:44)
Ну и быстродействие может сильно пострадать, особенно при многопоточке.
практика показывает, что не страдает. там, где идёт прямое обращение, компилятор сам оптимизирует вызовы в inline . так что по скорости это никак не отличается.
Практика - показывает что может всяко получится.
Например, пусть класс реализует визуальный элемент - эллипс.
При изменении размера по любой из полуосей его нужно перерисовать.
Наследник - круг, при изменении любой полуоси должен изменять синхронно другую.
Если доступ к полуосям эллипса только через геттеры и сеттеры, которые обеспечивают перерисовку элемента при изменении, то круг неизбежно будет дёргаться.
Что приведёт к уродскому интерфейсу.
Другой пример - многопоточный логгер. Пишет в файл, который создаётся в конструкторе и закрывается в деструкторе. Все операции защищает мутексом.
Мы хотим сделать наследника, которрый обеспечивает ротирование логов.
Если мы дадим доступ к мутексу клиентам (прямой или через геттер), то и есть прямая возможность нарушить инвариант класса и получить дедлоки...
А если доступ у мутексу получить нельзя, мы не сможем атомарно переоткрыть файл для организации ротирования.
Причём в обоих этих случаях о каких-либо инлайнах можно забыть - всё на уровне логики.
Цитата(Iron Bug @ 31.3.2010, 18:30)
Цитата(Tonal @ 31.3.2010, 9:44)
Ну дак давай пойдём до конца: какую сигнатуру должен иметь оператор
+ или
new?
И что они должны делать при возникновении ошибок?
Что и как должен возвращать конструктор?
это уже демагогия. речь шла о функциях. как известно, операторы - особые функции. впрочем, за последние N лет мне ни разу не потребовалось переписывать оператор +, к примеру. просто перегрузка оператора - это довольно экзотическое требование, которое больше относится к удобству программирования, чем к эффективности.
а оператор new имеет строгое формальное описание. мы тут не спорим о синтаксисе С++.
Демагогия - набор полемических приёмов вводящих заблуждение.
Я никого в заблуждение не вводил, а предложил довести твоё утверждение до логического конца (явного противоречия) для того, чтобы выявить границы его применимости.
Сигнатура операторов может изменятся в довольно широких пределах - см. например
operator().
А насчёт экзотики - это опять же именно твоё личное мнение, обусловленное тем, что ты видимо мало работала в областях связанных с массовыми расчётами.
У меня есть знакомая библиотека расчётов для векторной графики написанная на С++ в 94-96гг по мотивам реализаций на Fortran и Pascal.
Где-то в 2003 была попытка перевода её на Delphi - провалилась.
Удобство использования совмещения (перегрузки) операторов оказалась критичным.
А если смотреть с точки зрения чистого С на объекты - это всего лишь чуть более удобный способ записи структуры, функций работающий с ней и таблиц указателей на такие функции.
Так какая же сигнатура должна быть у конструкторов, функции std::strlen, std::string::size(), std::find, std::sort, и остальных?
Цитата(Iron Bug @ 31.3.2010, 18:30)
что значит "сообщить пользователю" когда, к примеру, ты управляешь системой реального времени? ругнуться в свой лог? пользы от этого - ноль. там уже накроется всё оборудование, железяки покорёжит, пока ты пишешь своё "сообщение пользователю". в реальном времени нет возможности пространного ввода-вывода и ассертов. всё решается проще - возврат 0 или 1. через регистры. очень быстро и просто. а типизирование при рантайме не помогает. пришло тебе ошибочное число от аппаратуры и надо его обрабатывать. а как ты заранее предугадаешь, что может прийти?
так что далеко не везде есть возможность развёрнутых сообщений об ошибках и отлова десятков исключений с перебором, чего же там всё-таки попалось. это очень замедляет и усложняет работу софта.
Пользователь здесь - это тот код, который вызвал функцию.
Сообщить ему - это значит стандартным для твоей системы образом просигнализировать об этом.
Т. е. возвратить код ошибки, или установить код операции, или вызвать исключение, или показать сообщение.
В любом случае, у системы/библиотеки/модуля должен быть стандартный способ такой сигнализации.
0 и 1 через регистры это очень хорошо и быстро, а что делать, если у тебя система работает с серверами баз данных, SOAP и DCOM.
И с одним из них пропала связь или возникла какая другая критическая ошибка?
Критическая здесь - это когда код на данном уровне не может принять решение по её обработке самостоятельно.
Какую 1 или 0 ты будешь через регистры передавать?
Т. е. тебе придётся эти ошибки ка-то классифицировать и передавать о них информацию, чтобы на верхнем уровне она была доступна и её было достаточно для принятия решений.
Кроме того, в случае с кодами возврата и результатом операций, у тебя нет возможность гарантировать что клиентский код не забудет их проверить и при проверке правильно проинтерпретирует.
А при возбуждении исключения, ты во первых явно передаёшь нужные данные в объекте, во вторых, если исключение не обработают оно уедет на следующий уровень - т. е. нечаянно проигнорировать критическое событие не получится.
Ну и "ошибочное число от аппаратуры" придти не может.
Это программа может быть написана так, что она ломается, когда приходят какие-то значения. Например браузер и ОС не должны "упать" если в ответ на запрос www.microsoft.com придёт мусор из свапфайла.
Это как раз внешние границы системы, только тут клиентами выступают не человек или код, а железки. И их данные нужно проверять на допустимость обязательно.
А вот во внутренних функциях - все даные уже обязаны быть проверены - в ином случае это ошибка кодирования.
Именно тут рулит типизация и ассерты.
Цитата(Iron Bug @ 31.3.2010, 18:30)
Цитата(Tonal @ 31.3.2010, 9:44)
Ежели ты работаешь с зоопарком библиотек, то кто тебе сможет гарантировать одинаковые стратегии обработки ошибок в них?
...
Стандарты на сигнатуру - кто-то возвращает код ошибки как результат, а кто-то в параметре.
ну, практически все функции возвращают 0 при удачном завершении. а остальное - в параметрах. по крайней мере, хардварные программеры придерживаются такой идеологии и разнообразия мнений как-то особо не наблюдается.
Хардварь - не единственная область применения С++, не говоря уже о других языках.