Это все еще верно.
Еще больше, чем программное обеспечение OO, база данных страдает, если это не рассматривают точно предназначенный путь. И это не было предназначено, что необходимо вставить некоторый уровень абстракции перед ним.
я думаю о непроницаемых уровнях абстракции как пытающийся создать замок Lego со всеми частями, закрытыми в наволочку. SQL чертовски труден, чтобы сделать правильно. Это не совместно использует много шаблонов с процедурным программированием и лучших практик для, можно быть противоположным для другого. Необходимо быть в состоянии к grok каждый объект в SQL-операторе и иметь довольно хорошую идею, что это предназначается, чтобы сделать, и что это на самом деле делает.
Партии людей, кажется, думают, что, как подковы, близко достаточно хорошо - если правильный ответ высовывается, который подразумевает, что Вы почти там. В SQL это просто не верно.
RoR и шаблон ActiveRecord по достоинству заработали репутацию пожирателей ресурсов DBMS поэтому. Оптимизированный дизайн ActiveRecord является, как правило, субоптимальным дизайном SQL, потому что это поощряет разложение SQL-оператора.
Компилятор C ++ не мешает вам использовать неинициализированные указатели, и, хотя результаты не определены, в реальном мире компиляторы обычно генерируют код, игнорирующий тот факт, что указатель не инициализирован. .
Это одна из причин, почему C ++ является одновременно быстрым и (сравнительно) опасным по сравнению с некоторыми другими языками.
Причина, по которой ваш вызов func2
успешен, заключается в том, что он не касается его этот
указатель. Значение указателя никогда не используется, поэтому не может вызвать проблемы. В func1
вы делаете используете указатель this
(для доступа к переменной-члену), поэтому он дает сбой.
Это полностью зависит от компилятора и не определено в соответствии со стандартом. Вы не должны полагаться на это.
Вызов func2 ()
завершается успешно, потому что точный метод вызова известен во время компиляции (вызов не является виртуальным) и сам метод не разыменован этот указатель . Итак, недопустимый , этот - это нормально.
ptr->func1(); // This works
, потому что компилятор получает указание вернуть ссылку на член класса. Для этого он просто добавляет смещение члена к недопустимому значению this указателя, и это создает еще один недопустимый указатель (ссылка, которая почти такая же).
int crashere=ptr->func1();// Crashes here
, потому что теперь компилятор получает инструкции чтобы получить значение по этой недопустимой ссылке, и это привело к сбою программы.
Я подозреваю, что ptr-> func2 ()
оптимизирован, поскольку он всегда возвращает истину. Но, как говорит Ричи, использование указателя в этом случае нормально, поскольку вы не касаетесь никаких данных экземпляра (а), и поэтому не к чему врезаться.
Не работает. Просто по счастливой случайности ваше приложение не вылетает там, где вы ожидаете. Это не функция, а побочный эффект компилятора, который позволяет вызову функции казаться работоспособным.
В C ++ есть понятие неопределенного поведения. Использование неинициализированного указателя - типичный пример такого неопределенного поведения. По соображениям производительности стандарт C ++ не накладывает никаких ограничений на возможный результат. Другими словами, форматирование жесткого диска совершенно приемлемо.
Вы можете вызывать методы, используя неинициализированные указатели. Это будет работать либо ptr-> func1 (); или int crashere = ptr-> func1 (); //