Daniro_San
@Daniro_San
Программист

Конструкторы и приравнивание в Си подобных языках?

Я тут разбираюсь с темой конструкторов.
Например такой у нас есть структура Example в C++ коде:
struct Example
{
     Example ( const int &i ) {}
};

И ее аналог в C# коде:
// struct - что бы работать со стуктурой в стеке, аналогично примеру с плюсами
struct Example
{
    public Example ( System.Int32 i ){}
}

А теперь самое интересное:
C++ :
Example a ( 1 ) ; // Создаем обьект, вызываем конструктор
Example a = 1 ; // То же самое

C# :
Example a = new Example ( 1 ) ; // Создаем обьект и приравниваем его к Example (1)

То есть, не вызываем конструктор напрямую, а через извращенный синтаксис с new приравниваем наш обьект 'a' к обьекту возвращаемому конструкцией new Example (1) . По крайней мере я все понял именно так. Я правильно понял?
Если в плюсах все, что после объявления, даже с равно (=) - вызов конструктора, то в C# после объявления мы производим настоящее присваивание?
  • Вопрос задан
  • 671 просмотр
Пригласить эксперта
Ответы на вопрос 5
Nipheris
@Nipheris Куратор тега C++
К сожалению, все несколько сложнее, и вам нужно лучше разобраться, что происходит в обоих случаях.

В C++ жизненный цикл объекта, место и способ его существования определяется кодом, создающим объект. Иными словами, тот код, который ИСПОЛЬЗУЕТ класс, определяет, автоматическая ли будет создана переменная (Example a(..)), или динамическая (new Example(..)). Да, в коде класса можно ограничить использующий код, запретив использование конструктора копирования и оператора присваивания, но изначально дизайн языка подразумевает принятие решения не "создателем" класса/структуры, а её "пользователем".

В C# поведение переменной типа класса/структуры зависит прежде всего от самого класса/структуры. Экземпляры классов, т.е. reference-типов, создаются с динамическим жизненным циклом, и для них работает механизм подсчета ссылок и сборка мусора. Экземпляры структур создаются с автоматическим жизненным циклом, переменные структур хранят значения структур, а не ссылки на них.

Иными словами, выражение new T(...) - это просто унифицированный синтаксис создания экземпляра типа, независимый от природы этого типа. Удобно это или не очень - отдельный разговор, однако в текущем дизайне языка это достаточно логично (особенно в контексте generic-ов). Аналогично, T a - унифицированный синтаксис объявления переменной типа.

Нельзя слепо сравнивать то, что происходит в C# и в C++.
Ответ написан
@dmitryKovalskiy
программист средней руки
Нет, вы не правы. оператор = это оператор присваивания и скрытых действий в C# не имеет. Разница в том что синтаксис C++ "Example a" создает объект. Аналогичная запись на C# создает ссылку на объект в стеке, а будет создан сам объект или нет - забота других инструкций.
То есть, не вызываем конструктор напрямую, а через извращенный синтаксис с new приравниваем наш обьект 'a'

Вы не вызываете конструктор напрямую. new это вызов конструктора, а не "извращенный синтаксис". Не хотите new? ради бога - пишите фабрики, методы создания объектов и прочее.
Ответ написан
OnYourLips
@OnYourLips
Для C# удобнее писать так:

var a = new Example(1) ;
Не нужно повторять тип.
Ответ написан
Комментировать
maaGames
@maaGames
Погроммирую программы
struct Example
{
    explicit Example ( const int &i ) {}
};


И код на С++ будет эквивалентен коду на C#. Т.к. не "то же самое", а неявное приведение типа.
Ответ написан
yarosroman
@yarosroman Куратор тега C#
C# the best
На С++ тоже можно писать Example a = new Example(), а можно как вы написали, но если вы не понимаете разницу в этих выражениях, то вам следует дальше книги читать. Если вы напишете Example a(1), то переменная будет уничтожена при выходе из области видимости, а при Example a = new Example(1), будет лишь уничтожена переменная-ссылка на объект, сам же объект останется в памяти, при этом ссылку на объект можно вернуть из функции, например если вы пишете функцию-фабрику. Однако если вы все таки в функции напишите Example a(1), и вернете ссылку из функции, то объект все равно будет уничтожен, а вы получите ссылку на несуществующий объект. В С++ есть несколько классов "умных указателей", которые работают аналогично указателям C#.

Плюс разница между структурами и классами с C# и C++ колоссальна. В C++ труктура это класс у которого все члены по умолчанию имеют уровень доступа по умолчанию public, вместо private в классах, то в C# это синтаксически, семантически разные вещи с различным поведением.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы