Полноценность имеет документацию - легче отличить создания объекта от вызовов метода, чем в Python.
причина является исторической, и прибывает прямо из синтаксиса C++. В C++, "Class1 ()" является выражением, создающим экземпляр Class1 на стеке . Например: векторизуйте = вектор (); В этом случае вектор создается и копируется в вектор (оптимизатор может удалить избыточную копию в некоторых случаях).
Вместо этого "новый Class1 ()" создает экземпляр Class1 на "куче" , как в Java и C#, и возвращается указатель к нему, с другим синтаксисом доступа, в отличие от Java и C++. На самом деле значение новых может быть переопределено для использования любого средства выделения специального назначения, которое все еще должно относиться к некоторой "куче", так, чтобы полученный объект мог быть возвращен ссылкой.
, Кроме того, в Java/C#/C ++, Class1 () отдельно мог обратиться к любому методу/функции, и это будет сбивать с толку. Конвенция кодирования Java на самом деле избежала бы, чтобы, так как они требуют, чтобы имена классов начали с прописной буквы и имен методов запускаться с нижнего регистра один, и вероятно это было способом, которым Python избегает беспорядка в этом случае. Читатель ожидает, "что Class1 ()" создаст объект, "class1 ()", чтобы быть вызовом функции, и "x.class1 ()", чтобы быть вызовом метода (где 'x' может быть 'сам').
Наконец, с тех пор в Python они приняли решение заставить классы быть объектами и вызываемыми объектами, в частности, синтаксис без 'нового' будет позволен, и это было бы непоследовательно, чтобы позволить иметь также другой синтаксис.
Class1 obj = Class1();
В C# и Java, Вам нужно "новое" ключевое слово, потому что без него, он рассматривает "Class1 ()" как вызов к методу, имя которого является "Class1".
Новый оператор в C# отображается непосредственно на инструкцию IL, названную newobj
, который на самом деле выделяет место для переменных нового объекта и затем выполняет конструктора (названный .ctor в IL). При казни конструктора - во многом как C++ - ссылка на инициализированный объект передается в как невидимый первый параметр (как thiscall).
подобная thiscall конвенция позволяет времени выполнения загружаться и JIT весь код в памяти для определенного класса только в один раз и снова использовать его для каждого экземпляра класса.
Java может иметь подобный код операции на своем промежуточном языке, хотя я не достаточно знаком для высказывания.
Новый оператор выделяет память для объекта (объектов), который является, это - цель; поскольку Вы говорите это также сам документы , который экземпляр (экземпляры) (т.е. новый) Вы работаете с
C++ предлагает программистам выбор выделения объектов на "куче" или на стеке.
Стековое выделение более эффективно : выделение является более дешевым, затраты на освобождение являются действительно нулем, и язык оказывает помощь в разграничении объектных жизненных циклов, снижая риск упущения освободить объект.
, С другой стороны, в C++, необходимо быть очень осторожными при публикации или совместном использовании ссылок на стековые объекты, потому что стековые объекты автоматически освобождены, когда стековый фрейм раскручен, ведя к висячим указателям.
С new
оператор , все объекты выделяются на "куче" в Java или C#.
Class1 obj = Class1 ();
На самом деле, компилятор попытался бы найти метод названным Class1()
.
, Например, следующее общая ошибка Java:
public class MyClass
{
//Oops, this has a return type, so its a method not a constructor!
//Because no constructor is defined, Java will add a default one.
//init() will not get called if you do new MyClass();
public void MyClass()
{
init();
}
public void init()
{
...
}
}
<час> Примечание: "все объекты выделяются на "куче"", не означает, что выделение стека иногда не используется под капотом.
, Например, в Java, оптимизации Горячей точки как escape-анализ использование складывает выделение.
Этот анализ, выполненный компилятором во время выполнения, может прийти к заключению, например, что на объект на "куче" ссылаются только локально в методе, и никакая ссылка не может сбежать из этого объема. Если так, Горячая точка может применить оптимизацию во время выполнения. Это может выделить объект на стеке или в регистрах вместо на "куче".
Такая оптимизация, хотя не всегда , рассмотрела решающий ...
В дополнение к комментариям выше AFAIK они планировали удалить новое ключевое слово для Java 7 в ранних проектах. Но позже они отменили его.
Причина Java выбрал его, состояла в том, потому что синтаксис был знаком разработчикам C++. Причина C# выбрал его, состояла в том, потому что это было знакомо Java-разработчикам.
причина new
, оператор используется в C++, состоит, вероятно в том, потому что с ручным управлением памятью очень важно прояснить, когда память выделяется. В то время как pythonesque синтаксис мог работать, он делает, менее очевидно, что память выделяется.