What is actually the difference between System::String^ ex;
and System::String ex1;
?
I found out that the one with "^" means that it is top-level. But what does that mean?
-
1One is a tracked reference, one is not. – Kerrek SB Aug 21 '12 at 15:36
-
“top level”? What’s that supposed to mean? – Konrad Rudolph Aug 21 '12 at 15:42
-
To the people who closed this as a duplicate, please revert. One isn’t a duplicate, and one is age old and uses outdated / wrong terminology. – Konrad Rudolph Aug 21 '12 at 15:44
-
1The term 'top level' is used in several compiler messages. For example, `gcnew String^()` gives a compiler error of `error C3698: 'System::String ^' : cannot use this type as argument of 'gcnew' did you mean 'System::String' (without the top-level '^')?` – David Yaw Aug 21 '12 at 17:35
2 Answers
System::String^
is a reference to a managed string object, System::String
is a managed string object directly on the stack or inline in another class.
As mentioned in What does the caret (‘^’) mean in C++/CLI?, the ^
is a tracking reference, roughly equivalent to *
for a pointer in unmanaged code. In the same way you can have unmanagedClass* foo1;
and unmanagedClass foo2;
, you can have System::String^ str1;
and System::String str2;
When used without the ^
, it follows the same rules as an unmanaged class without the *
: Access methods on it with a .
not a ->
. Automatically cleaned up when it leaves scope (destructor in unmanaged, dispose method in managed).
One thing that does make working with managed objects without their ^
harder is that most managed objects don't define a copy constructor or the equals operator. Neither of those would be used in C# or VB, so they generally aren't implemented. Without them, it's impossible to assign a new value to a variable without a ^
, so you're generally limited to constructing just a single object.
C++/CLI has a feature called "stack semantics". It is meant to emulate the RAII pattern in C++, the compiler automatically emits a call to the destructor of the class when you declare a local variable of a reference type without the ^ hat.
This is not appropriate for the System::String class, it doesn't have a destructor.
Since it also doesn't have any useful constructors, you'll almost always just end up with a compiler error message when you try to declare it without the hat anyway. Always use the hat.

- 922,412
- 146
- 1,693
- 2,536