auto foo = ref новый Foo(); Что такое реф?

Я смотрел видео из //build/, и несколько разработчиков MS использовали подобный синтаксис в своих программах на C++11:

auto foo = ref new Foo();

Я понимаю, что делает в этой строке все, кроме "ref". Что это значит?


person Timothy Baldridge    schedule 23.09.2011    source источник
comment
Чтобы никто не понял неправильно: это не синтаксис C++11! Это расширение Майкрософт.   -  person TonyK    schedule 25.09.2011
comment
Вы должны проверить это видео Использование среды выполнения Windows из C++ channel9.msdn.com/events /BUILD/BUILD2011/TOOL-532T в 14:30   -  person KindDragon    schedule 26.09.2011


Ответы (3)


Готовящийся к выпуску компилятор Visual C++ добавляет этот синтаксис для работы с объектами WinRT (которые, в свою очередь, являются следующим поколением COM, через что мы уже прошли? COM, DCOM, COM+, ActiveX, ...)

Эта строка почти эквивалентна:

com_ptr_t<Foo> foo = CreateInstance<Foo>();

Но есть и новая версия com_ptr_t, использующая синтаксис Foo^.

person Ben Voigt    schedule 23.09.2011
comment
Это кажется мне несколько радикальным нарушением синтаксиса. Я не знаю WinRT, но создает ли это динамический экземпляр в куче C++ (собственной)? - person Kerrek SB; 23.09.2011
comment
@KerrekSB: почти уверен, что он использует распределитель ОС, как это традиционно делали объекты COM (но, как и все остальное, я уверен, что вместо старый добрый распределитель COM). Таким образом, это динамический экземпляр в куче, а не куча, управляемая средой выполнения C++ и используемая для new и delete. - person Ben Voigt; 23.09.2011
comment
Когда такая ссылка выходит за рамки, освобождается ли объект? - person Jörgen Sigvardsson; 23.09.2011
comment
@JörgenSigvardsson: есть автоматический подсчет ссылок, вроде boost::shared_ptr. com_ptr_t уже сделал это. Почему они ввели специальный синтаксис для чего-то, встроенного в C++, я не знаю. - person Ben Voigt; 23.09.2011
comment
@Ben IIRC, распределитель для объектов (как и в случае с vanilla COM) технически является деталью реализации фабрики классов, и ему даже не нужно находиться в куче, если время жизни объекта правильно соответствует AddRef / Release. - person Pavel Minaev; 24.09.2011
comment
@Ben Я не утверждаю, что знаю конкретные причины этого дизайнерского решения, но одна вещь, которая сразу же приходит на ум после нескольких лет написания кода C ++ и COM в ATL, заключается в том, что интеллектуальные указатели, реализованные как классы шаблонов, плохо работают с API, который их не использует - в конечном итоге вам придется явно оборачивать/разворачивать необработанные указатели в умные на границе API. Особенно неприятный случай, когда указатель является выходным параметром, поэтому вам в конечном итоге нужно предоставить необработанную переменную указателя для этого, прежде чем обернуть его, или же перегрузить унарный &, как это делает ATL, и сломать STL. - person Pavel Minaev; 24.09.2011
comment
@PavelMinaev: перегруженный operator& больше не является нарушением ограничений STL. Во-вторых, API-интерфейсы, разработанные для написания новых материалов, могут просто взять com_ptr_t. Тем не менее, Херб Саттер сказал, что они почти сделали это только библиотекой на C++, но были некоторые странные пограничные случаи, которые приводили к очень плохой производительности в качестве библиотеки, и им пришлось сделать это языком, чтобы решить их. Сами усовершенствования синтаксиса уже были в компиляторе для C++/CLI. - person Puppy; 24.09.2011
comment
@DeadMG: У вас случайно нет ссылки на подробности Херба Саттера по этому поводу? - person Ben Voigt; 24.09.2011
comment
@DeadMG Чистый API C++ может принимать com_ptr_t, но переносимый ABI не может, если только вам не требуется очень конкретное представление для интеллектуального указателя (поэтому, например, вы не можете использовать ATL CComPtr<T> в сигнатурах методов при написании COM-компонентов сегодня и должны принимать/возвращать необработанные указатели). Конечно, VC++ уже размещает виртуальные таблицы очень специфическим образом для COM... - person Pavel Minaev; 26.09.2011
comment
По моему скромному мнению, да, это действительно злоупотребление синтаксисом, возможно, Microsoft не следует за ним, сохраняйте его простым и чистым, подумайте о Google, Apple, ECC... если добавить некоторый синтаксис в С++... - person LXG; 04.07.2013

«ref new» — это ключевое слово с двумя токенами. Он указывает компилятору создать экземпляр объекта среды выполнения Windows и автоматически управлять временем жизни объекта (через оператор «^»).

Создание экземпляра объекта среды выполнения Windows вызывает выделение, но он не обязательно должен находиться в куче.

person ReinstateMonica Larry Osterman    schedule 24.09.2011
comment
Являются ли эталоны значениями/эталонами двойного режима? Когда ссылка выходит за пределы области действия, рассматривается ли она как CComPtr‹T›? Можно ли создать экземпляр класса ref в стеке, как обычные классы? Будет ли WinRT/C++/CX поддерживать мой старый код на основе COM (интерфейсы, а также реализации на основе ATL)? Извините за шквал вопросов... - person Jörgen Sigvardsson; 24.09.2011
comment
Это не ссылки — ref new — это ключевое слово языка, точно так же, как new и __gcnew. Таким образом, вы не можете создать их экземпляр в стеке (можете ли вы создать экземпляр указателя в стеке?). WinRT — это набор API и набор шаблонов API, поэтому бессмысленно говорить, что он поддерживает код на основе COM. C++/CX поддерживает классические API-интерфейсы COM, точно так же, как C++/CLI поддерживает классические API-интерфейсы COM. Вы можете использовать ATL в приложении C++/CX или использовать новую библиотеку шаблонов WRL (ComPTR‹T›). - person ReinstateMonica Larry Osterman; 24.09.2011
comment
Я не видел никаких явных вызовов Release() ни в одном примере, поэтому я предполагаю, что компилятор вводит вызов Release(), когда дескриптор/указатель/ссылка (как бы они ни назывались в CX) выходят за рамки. Это верное предположение? - person Jörgen Sigvardsson; 25.09.2011
comment
Это правильно - это то, что я имел в виду под автоматическим управлением временем жизни объекта. - person ReinstateMonica Larry Osterman; 26.09.2011
comment
Из того, что я прочитал в msdn, ссылки ^ содержат два указателя, один на объект и один на определение класса, и их удаление создания ведет себя так же, как и Shared_ptr С++ 11. Моя гипотеза относительно указателя на определение класса, поскольку объекты WinRT были сделаны так, чтобы их можно было легко передать пакетам на других языках WinRT (C# и JavaScript). (msdn.microsoft.com/en-us/library/windows /apps/hh699870.aspx) - person Jules G.M.; 20.11.2012

ref в данном случае означает подсчет ссылок. Классы, использующие ref, являются компонентами WinRT, в которых есть готовые механизмы подсчета ссылок.

person Claudio Junior    schedule 18.10.2011