auto foo = ref new Foo(); What is "ref"?
Asked Answered
H

3

23

I was watching a video from, //build/ and several of the MS developers were using a syntax like this in their C++11 programs:

auto foo = ref new Foo();

I understand what everything does in this line except "ref". What does that mean?

Haha answered 23/9, 2011 at 14:0 Comment(2)
Just so nobody gets the wrong idea: This is not C++11 syntax! It's a Microsoft extension.Basting
You should check this video "Using the Windows Runtime from C++" channel9.msdn.com/events/BUILD/BUILD2011/TOOL-532T at 14:30Rhodium
P
10

The forthcoming Visual C++ compiler adds this syntax for dealing with WinRT objects (which are in turn the next generation of COM, what have we gone through now? COM, DCOM, COM+, ActiveX, ...)

That line is nearly equivalent to:

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

But there's a new version of com_ptr_t as well, using the syntax Foo^.

Puri answered 23/9, 2011 at 14:14 Comment(10)
That strikes me as a somewhat radical syntax abuse. I don't know WinRT, but does this create a dynamic instance on the C++ (native) heap?Lallygag
@KerrekSB: Pretty sure it uses an OS allocator, like COM objects have traditionally done (but like everything else, I'm sure there's a new and improved WinRT allocator instead of the good-ol' COM allocator). So it's a dynamic instance on a heap, but not the heap managed by the C++ runtime and used for new and delete.Puri
When such a reference goes out of scope, is the object released?Berky
@JörgenSigvardsson: There's automatic reference counting, sort of like boost::shared_ptr. com_ptr_t already did that as well. Why they introduced a special syntax for something built into C++ I don't know.Puri
@Ben IIRC, the allocator for objects (just as with vanilla COM) is technically a class factory implementation detail, and doesn't even need to be on the heap - so long as object's lifetime is properly corresponding to AddRef / Release.Bordie
@Ben I don't claim to know the specific reasons for this design decision, but one thing that immediately comes to mind from several years of writing C++ & COM code in ATL is that smart pointers implemented as template classes don't play well with an API that does not use them - you end up having to explicitly wrap/unwrap raw pointers into smart ones at the API boundary. A particularly nasty case is when pointer is an out parameter - so you end up having to provide a raw pointer variable for that before wrapping it - or else overload unary & like ATL does and break STL.Bordie
@PavelMinaev: Overloaded operator& is no longer a violation of STL constraints. Secondly, APIs designed to be written with the new stuff could just take a com_ptr_t. However, Herb Sutter said that they very nearly did make it library-only in C++, but there were some strange edge cases which produced very bad performance as a library and they had to make it language to solve them. The syntax enhancements themselves were already in the compiler for C++/CLI.Mell
@DeadMG: Would you happen to have a link to Herb Sutter's details on this?Puri
@DeadMG A pure C++ API can take a com_ptr_t, but a portable ABI can't, unless you demand a very specific representation for the smart pointer (which is why e.g. you can't use ATL CComPtr<T> in method signatures when writing COM components today, and have to take/return raw pointers). Granted, VC++ already lays out vtables in a very specific way for COM...Bordie
In my humble opinion, Yes this is really syntax abuse, maybe microsoft don't follow "keep it easy and clean", think about google, apple, ecc... if add some syntax to c++...Clifford
G
8

"ref new" is a 2 token keyword. It instructs the compiler to instantiate a windows runtime object and automatically manage the lifetime of the object (via the "^" operator).

Instantiating a windows runtime object causes an allocation, but it does not have to be on the heap.

Guru answered 24/9, 2011 at 13:43 Comment(5)
Are the references dual mode values/refernces? When a reference goes out of scope, is it treated as if it was a CComPtr<T>? Can a ref class be instantiated on the stack like regular classes? Will WinRT/C++/CX support my old COM based code (interfaces as well as ATL based implementations)? Sorry for the burst of questions...Berky
These aren't references - "ref new" is a language keyword, just like "new" is and "__gcnew" is. As such, you can't instantiate them on the stack (can you instantiate a pointer on the stack?). WinRT is a collection of APIs and a set of API patterns, so it's meaningless to say it supports COM based code. C++/CX supports classic COM APIs, just like C++/CLI supports classic COM APIs. You can use ATL in a C++/CX application, or you can use the new WRL template library (ComPTR<T>).Guru
I have not seen any explicit calls to Release() in any example, so I'm guessing the compiler injects a call to Release() when the handle/pointer/reference (whatever they're called in CX) goes out of scope. Is that a correct guess?Berky
That's correct - that's what I meant by "automatically manage the lifetime of the object"Guru
From what I read on msdn, the ^ references contain two pointers, one to the object and one to the class definition, and their creation deletion behaves the same way as a C++11 shared_ptr would behave. My hypothesis for the pointer to the class definition because WinRT objects were made to be easy to pass on to packages in other WinRT languages (C# and JavaScript). (msdn.microsoft.com/en-us/library/windows/apps/hh699870.aspx)Talkfest
B
2

ref in this case stands for reference counting. Classes using ref are WinRT component which have reference count machanisms out of the box.

Breton answered 18/10, 2011 at 1:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.