[VS2008 C++]Problem z deklaracją zmiennej

0

Witam,

Pytanie początkującego, chcąc korzysać ze zmiennej Mode typu String gdzie muszę ją zadeklarować na początku programu?
Deklaruje tak: String^ Mode = "test".
Próbowałem w pliku źródłowym Form1.h w miejscu:
...
namespace grafika_cwiczenia {
String^ Mode = "test";
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Forms;
using namespace System::Data;
using namespace System::Drawing;
public ref class Form1 : public System::Form
...

Kompilator wywala: error C3145: 'Mode' : global or static variable may not have managed type 'System::String ^'.

Dla porównania deklaracja np. Int32 test przechodzi bez problemu zatem czemu nie pasuje mu String? Próbowałem deklarować w innych miejscach projektu ale bezskutecznie.

Niech ktoś mnie wyprowadzi z błędu ;)

0
********
#pragma endregion
	   
	String ^JakisText;

********
0

Kompilator wywala: error C3145: 'Mode' : global or static variable may not have managed type 'System::String '.
Czyli: Zmienna globalna lub statyczna nie może mieć zarządzanego typu 'System::String
'.
Chyba dość jasne?

Dla porównania deklaracja np. Int32 test przechodzi bez problemu zatem czemu nie pasuje mu String? Próbowałem deklarować w innych miejscach projektu ale bezskutecznie.

Bo System::Int32 to value

-type, a `System::String` to <code noframe>ref

-type. Te drugie mogą być tylko w klasie zarządzanej (ref class/ref struct/value class/value struct).
Rozwiązaniem jest:
• użycie stringa natywnego std::string

• użycie <code noframe>String^

wewnątrz klasy zarządzanej
• użycie auto_gcroot

, ale to berzyydkie jest:

```cpp
   using namespace System;

   #include <msclr\auto_gcroot.h>
   using namespace msclr;

   int main()
   {
       auto_gcroot<String^> str2; // natywne opakowanie dla typu zarządzanego
       str2.attach(gcnew String("foo bar baz"));

       auto_gcroot<String^> str1(gcnew String("ala ma kota")); // attach od razu przy konstrukcji

       Console::WriteLine(str2.get()); // get() pobiera zawarty obiekt
       Console::WriteLine(str2.get()->Length);
       Console::WriteLine(str2->Length);  // to samo co powyższe: przeciążony operator ->

       str1.release(); // zwalnia zawarty String^, oddając go garbage collectorowi

      /* wyższa filozofia: auto_gcroot na stercie */

      auto_gcroot<String^> *str3 = new auto_gcroot<String^>(gcnew String("ali kot zdechl"));
      Console::WriteLine(str3->get());
      Console::WriteLine(str3->get()->Length);
      //Console::WriteLine(str3->Length); // błąd: Length nie jest elementem str3
      Console::WriteLine((*str3)->Length); // trzeba go zmusić do przeciążenia operatora
      delete str3; // przy okazji zwolni zawartego stringa

      // tutaj następuje zniszczenie str1 (ale sam String^ zwolniono uprzednio)
      // obiekt zawarty w str2 też jest zwalniany, wraz z destrukcją str2.
   }

1 użytkowników online, w tym zalogowanych: 0, gości: 1