0

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?

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
Araw
  • 2,410
  • 3
  • 29
  • 57
  • 1
    One 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
  • 1
    The 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 Answers2

2

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.

Community
  • 1
  • 1
David Yaw
  • 27,383
  • 4
  • 60
  • 93
1

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536