vs2010 C++示例中'^'是什么意思?

时间:2022-12-31 00:40:26
C++
vs2010C++示例中有问题不懂: 
String^ str = "    A String!";'^'这个符号是何用意呢,请赐教

3 个解决方案

#1


clr
托管对象

#2


顶LS,C++/CLI。

#3


查MSDN是Windows程序员必须掌握的技能之一。
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_vclang/html/70c411e6-be57-4468-a944-6ea7be89f392.htm
Visual C++ Language Reference 
^ (Handle to Object on Managed Heap) 
Example  See Also  Send Feedback 
 

Declares a handle to an object on the managed heap.

Remarks
A handle to an object on the managed heap points to the "whole" object, and not to a member of the object.

See gcnew for information on how to create an object on the managed heap.

In Visual C++ 2002 and Visual C++ 2003, __gc * was used to declare an object on the managed heap. The ^ replaces __gc * in the new syntax.

The common language runtime maintains a separate heap on which it implements a precise, asynchronous, compacting garbage collection scheme. To work correctly, it must track all storage locations that can point into this heap at runtime. ^ provides a handle through which the garbage collector can track a reference to an object on the managed heap, thereby being able to update it whenever that object is moved.

Because native C++ pointers (*) and references (&) cannot be tracked precisely, a handle-to object declarator is used.

Member selection through a handle (^) uses the pointer-to-member operator (->). 

For more information, see How to: Declare Handles in Native Types.

Example
This sample shows how to create an instance of reference type on the managed heap. This sample also shows that you can initialize one handle with another, resulting in two references to same object on managed, garbage-collected heap. Notice that assigning nullptr to one handle does not mark the object for garbage collection.

  Copy Code 
// mcppv2_handle.cpp
// compile with: /clr
ref class MyClass {
public:
   MyClass() : i(){}
   int i;
   void Test() {
      i++;
      System::Console::WriteLine(i);
   }
};

int main() {
   MyClass ^ p_MyClass = gcnew MyClass;
   p_MyClass->Test();

   MyClass ^ p_MyClass2;
   p_MyClass2 = p_MyClass;

   p_MyClass = nullptr;
   p_MyClass2->Test();   
}
 
  Copy Code 
1
2
 

The following sample shows how to declare a handle to an object on the managed heap, where the type of object is a boxed value type. The sample also shows how to get the value type from the boxed object.

  Copy Code 
// mcppv2_handle_2.cpp
// compile with: /clr
using namespace System;

void Test(Object^ o) {
   Int32^ i = dynamic_cast<Int32^>(o);

   if(i)
      Console::WriteLine(i);
   else
      Console::WriteLine("Not a boxed int");
}

int main() {
   String^ str = "test";
   Test(str);

   int n = 100;
   Test(n);
}
 
  Copy Code 
Not a boxed int
100
 

This sample shows that the common C++ idiom of using a void* pointer to point to an arbitrary object is replaced by Object^, which can hold a handle to any reference class. It also shows that all types, such as arrays and delegates, can be converted to an object handle.

  Copy Code 
// mcppv2_handle_3.cpp
// compile with: /clr
using namespace System;
using namespace System::Collections;
public delegate void MyDel();
ref class MyClass {
public:
   void Test() {}
};

void Test(Object ^ x) {
   Console::WriteLine("Type is {0}", x->GetType());
}

int main() {
   // handle to Object can hold any ref type
   Object ^ h_MyClass = gcnew MyClass;

   ArrayList ^ arr = gcnew ArrayList();
   arr->Add(gcnew MyClass);

   h_MyClass = dynamic_cast<MyClass ^>(arr[0]);
   Test(arr);

   Int32 ^ bi = 1;
   Test(bi);

   MyClass ^ h_MyClass2 = gcnew MyClass;

   MyDel^ DelInst = gcnew MyDel(h_MyClass2, &MyClass::Test);
   Test(DelInst);
}
 
  Copy Code 
Type is System.Collections.ArrayList
Type is System.Int32
Type is MyDel
 

This sample shows that a handle can be dereferenced and that a member can be accessed via a dereferenced handle.

  Copy Code 
// mcppv2_handle_4.cpp
// compile with: /clr
using namespace System;
value struct DataCollection {
private:
   int Size;
   array<String^>^ x;

public:
   DataCollection(int i) : Size(i) {
      x = gcnew array<String^>(Size);
      for (int i = 0 ; i < Size ; i++)
         x[i] = i.ToString();
   }

   void f(int Item) {
      if (Item >= Size)
      {
         System::Console::WriteLine("Cannot access array element {0}, size is {1}", Item, Size);
         return;
      }
      else
         System::Console::WriteLine("Array value: {0}", x[Item]);
   }
};

void f(DataCollection y, int Item) {
   y.f(Item);
}

int main() {
   DataCollection ^ a = gcnew DataCollection(10);
   f(*a, 7);   // dereference a handle, return handle's object
   (*a).f(11);   // access member via dereferenced handle
}
 
  Copy Code 
Array value: 7
Cannot access array element 11, size is 10
 

This sample shows that a native reference (&) can’t bind to an int member of a managed type, .as the int may be stored in the garbage collected heap, and native references don’t track object movement in the managed heap. The fix is to use a local variable, or to change & to %, making it a tracking reference.

  Copy Code 
// mcppv2_handle_5.cpp
// compile with: /clr
ref struct A {
   void Test(unsigned int &){}
   void Test2(unsigned int %){}
   unsigned int i;
};

int main() {
   A a;
   a.i = 9;
   a.Test(a.i);   // C2664
   a.Test2(a.i);   // OK

   unsigned int j = 0;
   a.Test(j);   // OK
}
 

Requirements
Compiler option: /clr

See Also
Concepts
Language Features for Targeting the CLR
Send feedback on this topic to Microsoft.

#1


clr
托管对象

#2


顶LS,C++/CLI。

#3


查MSDN是Windows程序员必须掌握的技能之一。
ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.chs/dv_vclang/html/70c411e6-be57-4468-a944-6ea7be89f392.htm
Visual C++ Language Reference 
^ (Handle to Object on Managed Heap) 
Example  See Also  Send Feedback 
 

Declares a handle to an object on the managed heap.

Remarks
A handle to an object on the managed heap points to the "whole" object, and not to a member of the object.

See gcnew for information on how to create an object on the managed heap.

In Visual C++ 2002 and Visual C++ 2003, __gc * was used to declare an object on the managed heap. The ^ replaces __gc * in the new syntax.

The common language runtime maintains a separate heap on which it implements a precise, asynchronous, compacting garbage collection scheme. To work correctly, it must track all storage locations that can point into this heap at runtime. ^ provides a handle through which the garbage collector can track a reference to an object on the managed heap, thereby being able to update it whenever that object is moved.

Because native C++ pointers (*) and references (&) cannot be tracked precisely, a handle-to object declarator is used.

Member selection through a handle (^) uses the pointer-to-member operator (->). 

For more information, see How to: Declare Handles in Native Types.

Example
This sample shows how to create an instance of reference type on the managed heap. This sample also shows that you can initialize one handle with another, resulting in two references to same object on managed, garbage-collected heap. Notice that assigning nullptr to one handle does not mark the object for garbage collection.

  Copy Code 
// mcppv2_handle.cpp
// compile with: /clr
ref class MyClass {
public:
   MyClass() : i(){}
   int i;
   void Test() {
      i++;
      System::Console::WriteLine(i);
   }
};

int main() {
   MyClass ^ p_MyClass = gcnew MyClass;
   p_MyClass->Test();

   MyClass ^ p_MyClass2;
   p_MyClass2 = p_MyClass;

   p_MyClass = nullptr;
   p_MyClass2->Test();   
}
 
  Copy Code 
1
2
 

The following sample shows how to declare a handle to an object on the managed heap, where the type of object is a boxed value type. The sample also shows how to get the value type from the boxed object.

  Copy Code 
// mcppv2_handle_2.cpp
// compile with: /clr
using namespace System;

void Test(Object^ o) {
   Int32^ i = dynamic_cast<Int32^>(o);

   if(i)
      Console::WriteLine(i);
   else
      Console::WriteLine("Not a boxed int");
}

int main() {
   String^ str = "test";
   Test(str);

   int n = 100;
   Test(n);
}
 
  Copy Code 
Not a boxed int
100
 

This sample shows that the common C++ idiom of using a void* pointer to point to an arbitrary object is replaced by Object^, which can hold a handle to any reference class. It also shows that all types, such as arrays and delegates, can be converted to an object handle.

  Copy Code 
// mcppv2_handle_3.cpp
// compile with: /clr
using namespace System;
using namespace System::Collections;
public delegate void MyDel();
ref class MyClass {
public:
   void Test() {}
};

void Test(Object ^ x) {
   Console::WriteLine("Type is {0}", x->GetType());
}

int main() {
   // handle to Object can hold any ref type
   Object ^ h_MyClass = gcnew MyClass;

   ArrayList ^ arr = gcnew ArrayList();
   arr->Add(gcnew MyClass);

   h_MyClass = dynamic_cast<MyClass ^>(arr[0]);
   Test(arr);

   Int32 ^ bi = 1;
   Test(bi);

   MyClass ^ h_MyClass2 = gcnew MyClass;

   MyDel^ DelInst = gcnew MyDel(h_MyClass2, &MyClass::Test);
   Test(DelInst);
}
 
  Copy Code 
Type is System.Collections.ArrayList
Type is System.Int32
Type is MyDel
 

This sample shows that a handle can be dereferenced and that a member can be accessed via a dereferenced handle.

  Copy Code 
// mcppv2_handle_4.cpp
// compile with: /clr
using namespace System;
value struct DataCollection {
private:
   int Size;
   array<String^>^ x;

public:
   DataCollection(int i) : Size(i) {
      x = gcnew array<String^>(Size);
      for (int i = 0 ; i < Size ; i++)
         x[i] = i.ToString();
   }

   void f(int Item) {
      if (Item >= Size)
      {
         System::Console::WriteLine("Cannot access array element {0}, size is {1}", Item, Size);
         return;
      }
      else
         System::Console::WriteLine("Array value: {0}", x[Item]);
   }
};

void f(DataCollection y, int Item) {
   y.f(Item);
}

int main() {
   DataCollection ^ a = gcnew DataCollection(10);
   f(*a, 7);   // dereference a handle, return handle's object
   (*a).f(11);   // access member via dereferenced handle
}
 
  Copy Code 
Array value: 7
Cannot access array element 11, size is 10
 

This sample shows that a native reference (&) can’t bind to an int member of a managed type, .as the int may be stored in the garbage collected heap, and native references don’t track object movement in the managed heap. The fix is to use a local variable, or to change & to %, making it a tracking reference.

  Copy Code 
// mcppv2_handle_5.cpp
// compile with: /clr
ref struct A {
   void Test(unsigned int &){}
   void Test2(unsigned int %){}
   unsigned int i;
};

int main() {
   A a;
   a.i = 9;
   a.Test(a.i);   // C2664
   a.Test2(a.i);   // OK

   unsigned int j = 0;
   a.Test(j);   // OK
}
 

Requirements
Compiler option: /clr

See Also
Concepts
Language Features for Targeting the CLR
Send feedback on this topic to Microsoft.