В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.
При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.
Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».
Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this
. Возьмем этот пример:
public class Some {
private int id;
public int getId(){
return this.id;
}
public setId( int newId ) {
this.id = newId;
}
}
И в другом месте вашего кода:
Some reference = new Some(); // Point to a new object of type Some()
Some otherReference = null; // Initiallly this points to NULL
reference.setId( 1 ); // Execute setId method, now private var id is 1
System.out.println( reference.getId() ); // Prints 1 to the console
otherReference = reference // Now they both point to the only object.
reference = null; // "reference" now point to null.
// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );
// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...
Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference
и otherReference
оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.
Это - категорическая статья о "правильности константы": https://isocpp.org/wiki/faq/const-correctness.
, Короче говоря с помощью константы хорошая практика потому что...
, компилятор может оптимизировать его. Например, Вы защищены от
if( x = y ) // whoops, meant if( x == y )
В то же время, компилятор может генерировать более эффективный код, потому что это знает точно, чем состояние переменной/функции будет в любом случае. Если Вы пишете трудный код C++, это хорошо.
Вы корректны в этом, может быть трудно использовать правильность константы последовательно, но код конца более краток и более безопасен к программе с. Когда Вы делаете большую разработку C++, преимущества этого быстро проявляют.
Можно дать подсказки компилятора с константой также.... согласно следующему коду
#include <string>
void f(const std::string& s)
{
}
void x( std::string& x)
{
}
void main()
{
f("blah");
x("blah"); // won't compile...
}
Мне нравится правильность константы... в теории. К каждому разу, когда я попытался применить его строго на практике, это сломалось в конечном счете, и const_cast начинает вползать в создание ужасного кода.
, Возможно, это - просто шаблоны разработки, которые я использую, но константа всегда заканчивает тем, что была слишком широкой кистью.
, Например, вообразите простой механизм базы данных..., он имеет объекты схемы, таблицы, поля и т.д. У пользователя может быть 'указатель' Таблицы константы, означающий, что им не позволяют изменить саму схему таблицы..., но что относительно того, чтобы управлять данными, связанными с таблицей? Если Вставка () метод является отмеченной константой тогда внутренне, это должно выбросить мыс константы для фактического управления базой данных. Если это не отмеченная константа тогда, это не защищает от вызова метода AddField.
, Возможно, ответ должен разделить класс на основе требований мыса константы, но это имеет тенденцию усложнять дизайн больше, чем я хотел бы за преимущество, которое это приносит.
При использовании ключевого слова "константы" Вы определяете другой интерфейс к своим классам. Существует интерфейс, который включает все методы и интерфейс, который включает только методы константы. Очевидно, это позволяет Вам ограничить доступ к некоторым вещам, которые Вы не хотите измененный.
Да, это действительно становится легче со временем.
Существует хорошая статья здесь о константе в C++. Это - довольно прямое мнение, но надежда это помогает некоторым.
Скажите, что у Вас есть переменная в Python. Вы знаете, что Вы не , предположил изменять его. Что, если Вы случайно делаете?
C++ дает Вам способ защитить себя от случайного выполнения чего-то, что Вы, как предполагалось, не были в состоянии сделать во-первых. Технически можно обойти его так или иначе, но необходимо вставить дополнительную работу для стрельбы в.
Для встроенного программирования, с помощью const
рассудительно при объявлении глобальных структур данных может сохранить много RAM, заставив постоянные данные быть расположенным в ROM или флэш-памяти, не копируя в RAM во время начальной загрузки.
В повседневном программировании, с помощью const
тщательно помогает Вам постараться не писать программы, которые отказывают или ведут себя непредсказуемо, потому что они пытаются изменить строковые литералы и другие постоянные глобальные данные.
При работе с другими программистами на крупных проектах, использовании const
правильно помогает препятствовать тому, чтобы другие программисты регулировали Вас.
const
помогает Вам изолировать код, которые "изменяют вещи" за Вашей спиной. Так, в классе Вы отметили бы все методы, которые не изменяют состояние объекта как const
. Это означает, что const
экземпляры того класса больше не будут в состоянии назвать любого не - const
методы. Таким образом, Вы предотвращены от случайного вызова функциональности, которая может изменить Ваш объект.
кроме того, const
часть механизма перегрузки, таким образом, у Вас может быть два метода с идентичными подписями, но один с const
и один без. Тот с const
называют для const
ссылки, и другой требуется не - const
ссылки.
Пример:
#include <iostream>
class HelloWorld {
bool hw_called;
public:
HelloWorld() : hw_called(false) {}
void hw() const {
std::cout << "Hello, world! (const)\n";
// hw_called = true; <-- not allowed
}
void hw() {
std::cout << "Hello, world! (non-const)\n";
hw_called = true;
}
};
int
main()
{
HelloWorld hw;
HelloWorld* phw1(&hw);
HelloWorld const* phw2(&hw);
hw.hw(); // calls non-const version
phw1->hw(); // calls non-const version
phw2->hw(); // calls const version
return 0;
}
Моя философия - то, что, если Вы собираетесь использовать придирчивый в отношении гниды язык с проверками времени компиляции, чем, лучше всего используют его, Вы можете. const
осуществленный способ компилятора передать то, что Вы средний ... это лучше, чем комментарии или doxygen когда-либо будут. Вы платите цену, почему бы не получить значение?
Программирование C++ без константы похоже на управление без ремня безопасности на.
Это - боль для помещения ремня безопасности на каждый раз, когда Вы ступаете в автомобиль, и 364 из 365 дней, Вы прибудете безопасно.
единственная разница - то, что при входе проблему с автомобилем Вы будете сразу чувствовать его, тогда как с программированием без константы Вам, вероятно, придется искать в течение двух недель, что заставило тот катастрофический отказ только узнавать, что Вы непреднамеренно испортили аргумент функции, который Вы передали ссылкой неконстанты для эффективности.
При использовании константы строго Вы были бы удивлены, как немного реальных переменных там находятся в большинстве функций. Часто не больше, чем счетчик цикла. Если Ваш код достигает той точки, Вы получаете теплое чувство внутри... проверка компиляцией..., область функционального программирования является соседней..., можно почти коснуться его теперь...
константа является обещанием Ваш, делают как разработчик и включают в список справку компилятора в осуществление.
Мои причины того, чтобы быть корректным константой:
Это не для Вас, когда Вы пишете код первоначально. Именно для кого-то еще (или Вы несколько месяцев спустя) смотрит на объявление метода в классе или интерфейсе для наблюдения то, что это делает. Не изменение объекта является значительной информацией для подбирания из этого.
кажется каждый раз, что я отмечаю что-то как константу, я получаю ошибку и должен изменить некоторую другую функцию где-нибудь, чтобы быть константой также. Тогда это заставляет меня должным быть изменять другую функцию где-то в другом месте. Это - что-то, что просто становится легче с опытом?
На основе опыта, это - общий миф. Это происходит, когда не корректный константой находится с корректным константой кодом, уверенным. Если Вы разрабатываете корректный константой от запуска, это никогда не должно быть проблемой. Если Вы делаете что-то константой, и затем что-то еще не делает complile, компилятор говорит Вам что-то чрезвычайно важное, и необходимо не торопиться для фиксации его правильно .
Вот часть кода с распространенной ошибкой, от которой правильность константы может защитить Вас:
void foo(const int DEFCON)
{
if (DEFCON = 1) //< FLAGGED AS COMPILER ERROR! WORLD SAVED!
{
fire_missiles();
}
}
const correctness is one of those things that really needs to be in place from the beginning. As you've found, its a big pain to add it on later, especially when there is a lot of dependency between the new functions you are adding and old non-const-correct functions that already exist.
In a lot of the code that I write, its really been worth the effort because we tend to use composition a lot:
class A { ... }
class B { A m_a; const A& getA() const { return m_a; } };
If we did not have const-correctness, then you would have to resort to returning complex objects by value in order to assure yourself that nobody was manipulating class B's internal state behind your back.
In short, const-correctness is a defensive programming mechanism to save yourself from pain down the road.