C # объекты и C ++ объекты, разница - PullRequest
0 голосов
/ 16 ноября 2009

При создании экземпляра объекта как такового в C #

Myclass mc = new Myclass();

Этот mc теперь является ссылкой на объект Myclass, созданный в памяти. Это как «указатель» на эту память.

Это то же самое или сравнимо с этим в (Управляемом или Неуправляемом) C ++:

MyCppClass *mcCppClass = new MyCppClass();

Потому что это фактически создает указатель на экземпляр объекта класса.

Я просто пытаюсь выяснить, в чем именно заключаются различия?

Ответы [ 6 ]

4 голосов
/ 16 ноября 2009

Важным отличием, которое, кажется, еще никто не упомянул, является следующее:

Myclass mc = new Myclass();

в C #, это только правильный способ создания нового объекта. Когда вам нужен объект, вот как вы его создаете.

MyCppClass *mcCppClass = new MyCppClass();

В C ++ это то, как вы можете создать объект, и как иногда приходится создавать объект. Проблема с использованием этого подхода в C ++ заключается в том, что:

  • new является чрезвычайно медленным в C / C ++ по сравнению с управляемым языком. Если используется для выделения каждого нужного вам объекта, это будет больно.
  • Объект не имеет фиксированного времени жизни. Он размещается в куче и не уничтожается, пока вы не вызовете delete. Если вы забудете это сделать, он никогда не будет уничтожен. Если вы дважды наберете delete, ваша программа взорвется.

В C ++ у вас есть два способа создания объектов: Тот, который вы использовали выше:

// 1
MyCppClass *myobject = new MyCppClass();
delete myobject;

, но также изменен и включает вызов delete, потому что без него вы теряете память. Всякий раз, когда вы используете new, вы также должны рано или поздно позвонить delete , В общем, одно без другого - ошибка.

И второй, более распространенный подход:

// 2
MyCppClass myobject;

Второй, в некотором смысле, больше похож на ваш пример на C #. Его временем жизни автоматически управляет система (хотя способ управления им различен. В C ++ он длится до тех пор, пока не выйдет из области видимости, а в C # он длится до тех пор, пока никто не ссылается на него и не получает мусор - но в обоих случаях , вам не нужно ничего делать, чтобы убедиться, что он уничтожен). Как правило, это также правильный способ создания экземпляров объекта по той же причине.

Одна из наиболее распространенных ошибок, допущенных новыми программистами на C ++, заключается в использовании new для выделения каждого объекта, сохранения указателей на них, а затем попытки , чтобы не забыть удалить их. Более простое, надежное и эффективное решение - избегать new и избегать указателей, насколько это возможно. Иногда вам нужен объект, время жизни которого не ограничено объявленной областью действия (и где копирование объекта не является вариантом для использования его вне этой области). Затем вы используете new и, скорее всего, оберните полученный указатель в интеллектуальный указатель какого-либо типа.

0 голосов
/ 16 ноября 2009

Может называться ссылкой, но обрабатывается как указатель (может быть NULL). В C ++ ссылка не может быть нулевой, она всегда ссылается на тот же экземпляр.

В C ++ существует сильная разница между ссылками и указателями. И «ссылки» C # (или Java) ближе к указателям C ++, чем к ссылкам C ++.

int a = 3;
int b = 2;
int & c = b; // c and b will alway refer to the same thing.
c = a;    
std::cout << b << std::endl; // shows 3

int * pa = new int(3);
int * pb = new int(2);
int * pc = pb;
pc = pb; // pc and pb are now refering to different things

std::cout << *pb << std::endl;// shows 2

В C ++ вам не нужно размещать свои экземпляры в бесплатном хранилище («используя new»). Вы также можете объявить их в стеке. В последнем случае вам не нужно беспокоиться об их удалении.

0 голосов
/ 16 ноября 2009

Я думаю, что версия C # более аналогична reference в этом примере:

MyCppClass *mcCppClass = new McCppClass();
MyCppClass &reference = *mcCppClass;

В C ++ вам не нужно беспокоиться о том, что reference как бы указывает на ноль. Это просто там, так что вы используете это. Однако в C # ссылка на объект может быть нулевой.

Кроме того, как указал @Kyle Walsh, вы несете ответственность за удаление памяти, связанной с указателем mcCppClass в C ++. В C # ваш объект будет автоматически собираться мусором.

Следует помнить, что C # делает различие между классами и структурами. Классы являются ссылочными типами, а структуры - типами значений. В C ++ классы и структуры различаются только по уровню видимости членов по умолчанию (классы по умолчанию имеют видимость закрытых членов, а структуры по умолчанию имеют видимость открытых элементов). Это важное отличие, на которое следует обратить внимание при переходе с C ++ на C #. См. здесь для получения более подробной информации.

0 голосов
/ 16 ноября 2009

Они похожи, но есть несколько важных предостережений с версией C #:

  • Вы создаете объекты-значения и ссылки с помощью нового Blah (). Объекты-значения не ведут себя как ссылочные объекты: их назначение копирует данные, а не ссылку.

  • C # ссылочные объекты - сборщик мусора

0 голосов
/ 16 ноября 2009

Они равны в том смысле, что оба new выделяют память для переменных-членов. Они отличаются тем, что C ++ (в вашем примере) является указателем на объект в памяти и что C # имеет ссылку (которая не является указателем, но также не является ссылкой C ++, т. Е. Может быть нулевой).

Оба языка гарантируют, что результат new будет ненулевым, или выдает ошибку (то есть OutOfMemoryException в C #).

Конечно, в C ++ и C # поведение объектов, классов и т. Д. В целом совершенно различно (сборка мусора, поведение автобокса, статический конструктор и т. Д.).

РЕДАКТИРОВАТЬ: Одна вещь, еще не упомянутая в других ответах: любой new в C ++ будет вызывать конструктор полной иерархии классов. C # только для одного наследования и будет вызывать только первый конструктор в иерархии или объектный ctor. В C #, если конструкторы не определены, new X() равно new object().

0 голосов
/ 16 ноября 2009

В C ++ вы несете ответственность за удаление этой памяти, тогда как в C # это не так. Это, наверное, самая большая разница, которую вы захотите запомнить.

Что касается сходства, то они оба являются объектами, выделенными кучей.

Здесь - хорошая статья о куче против стека в C #, которая может оказаться полезной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...