Строка (C++/CLI и C++/CX)

Среда выполнения Windows и среда CLR представляют строки в виде объектов, управление выделяемой памятью которых осуществляется автоматически. Это значит, что в случае выхода строковой переменной за пределы области видимости или завершении работы приложения явно отменять память для строки не требуется. Чтобы указать, что управление временем существования строкового объекта должно осуществляться автоматически, следует объявить тип string с помощью модификатора дескриптор объекта (^).

Среда выполнения Windows

Архитектура среды выполнения Windows требует реализации типа данных String в пространстве имен Platform. Для удобства в Visual C++ также предусмотрен тип данных string, являющийся синонимом для Platform::String в пространстве имен default.

Синтаксис

// compile with /ZW
using namespace Platform;
using namespace default;
   Platform::String^ MyString1 = "The quick brown fox";
   String^ MyString2 = "jumped over the lazy dog.";
   String^ MyString3 = "Hello, world!";

Требования

Параметр компилятора: /ZW

Среда CLR

При компиляции с параметром /clr компилятор преобразует строковые литералы в строки типа String. Для сохранения обратной совместимости с существующим кодом у этого правила есть два исключения:

  • Обработка исключений. Если появляется строковый литерал, компилятор перехватывает его как строковый литерал.

  • Определение шаблона. Если строковый литерал передается в качестве аргумента шаблона, компилятор не преобразует его в String. Обратите внимание, что строковые литералы, переданные в качестве универсального аргумента, повышаются до String.

В компиляторе также есть встроенная поддержка трех операторов, которые можно переопределять для настройки их поведения:

  • System::String^ operator +( System::String, System::String);

  • System::String^ operator +( System::Object, System::String);

  • System::String^ operator +( System::String, System::Object);

После передачи String компилятор при необходимости упаковывает, а затем объединяет объект (с помощью ToString) со строкой.

Примечание.

Курсор ("^") означает, что объявленная переменная является дескриптором управляемого объекта C++/CLI.

Дополнительные сведения см. в статье Строковые и символьные литералы (C++).

Требования

Параметр компилятора: /clr

Примеры

В следующем примере кода демонстрируется объединение и сравнение строк.

// string_operators.cpp
// compile with: /clr
// In the following code, the caret ("^") indicates that the
// declared variable is a handle to a C++/CLI managed object.
using namespace System;

int main() {
   String^ a = gcnew String("abc");
   String^ b = "def";   // same as gcnew form
   Object^ c = gcnew String("ghi");

   char d[100] = "abc";

   // variables of System::String returning a System::String
   Console::WriteLine(a + b);
   Console::WriteLine(a + c);
   Console::WriteLine(c + a);

   // accessing a character in the string
   Console::WriteLine(a[2]);

   // concatenation of three System::Strings
   Console::WriteLine(a + b + c);

   // concatenation of a System::String and string literal
   Console::WriteLine(a + "zzz");

   // you can append to a System::String^
   Console::WriteLine(a + 1);
   Console::WriteLine(a + 'a');
   Console::WriteLine(a + 3.1);

   // test System::String^ for equality
   a += b;
   Console::WriteLine(a);
   a = b;
   if (a == b)
      Console::WriteLine("a and b are equal");

   a = "abc";
   if (a != b)
      Console::WriteLine("a and b are not equal");

   // System:String^ and tracking reference
   String^% rstr1 = a;
   Console::WriteLine(rstr1);

   // testing an empty System::String^
   String^ n;
   if (n == nullptr)
      Console::WriteLine("n is empty");
}
abcdef

abcghi

ghiabc

c

abcdefghi

abczzz

abc1

abc97

abc3.1

abcdef

a and b are equal

a and b are not equal

abc

n is empty

В следующем примере показано, что предоставляемые компилятором операторы можно перегружать, и что компилятор будет искать перегрузку функции на основе типа String.

// string_operators_2.cpp
// compile with: /clr
using namespace System;

// a string^ overload will be favored when calling with a String
void Test_Overload(const char * a) {
   Console::WriteLine("const char * a");
}
void Test_Overload(String^ a) {
   Console::WriteLine("String^ a");
}

// overload will be called instead of compiler defined operator
String^ operator +(String^ a, String^ b) {
   return ("overloaded +(String^ a, String^ b)");
}

// overload will be called instead of compiler defined operator
String^ operator +(Object^ a, String^ b) {
   return ("overloaded +(Object^ a, String^ b)");
}

// overload will be called instead of compiler defined operator
String^ operator +(String^ a, Object^ b) {
   return ("overloaded +(String^ a, Object^ b)");
}

int main() {
   String^ a = gcnew String("abc");
   String^ b = "def";   // same as gcnew form
   Object^ c = gcnew String("ghi");

   char d[100] = "abc";

   Console::WriteLine(a + b);
   Console::WriteLine(a + c);
   Console::WriteLine(c + a);

   Test_Overload("hello");
   Test_Overload(d);
}
overloaded +(String^ a, String^ b)

overloaded +(String^ a, Object^ b)

overloaded +(Object^ a, String^ b)

String^ a

const char * a

В следующем примере показано, что компилятор различает собственные строки и строки String.

// string_operators_3.cpp
// compile with: /clr
using namespace System;
int func() {
   throw "simple string";   // const char *
};

int func2() {
   throw "string" + "string";   // returns System::String
};

template<typename T>
void func3(T t) {
   Console::WriteLine(T::typeid);
}

int main() {
   try {
      func();
   }
   catch(char * e) {
      Console::WriteLine("char *");
   }

   try {
      func2();
   }
   catch(String^ str) {
      Console::WriteLine("String^ str");
   }

   func3("string");   // const char *
   func3("string" + "string");   // returns System::String
}
char *

String^ str

System.SByte*

System.String

См. также

Расширения компонентов для .NET и UWP
Строковые и символьные литералы
/clr (компиляция среды выполнения)