[.net] C++, .Net and the ^ operator...

Started by
7 comments, last by ZMaster 18 years, 4 months ago
Hi. Currently I'm trying to get a little into .Net programming in managed C++. I'm using Visual C++ 2005 EE and the .Net Framework 2. Now, I'm somehow confused by the ^ operator. I found out that this one is similiar to the * (pointer) operator in native C++ with the difference of creating an object on the managed heap that uses a garbage collector. Well... that sounds great, but: 1) Some objects have to be declared with the ^ operator. For example: System::String^ sTest; Why that? Does System::String^ sTest2 = sTest; copy the string or just the pointer to the object on the heap??? 2) If System::Boolean^ bTest represents a reference to an object on the heap, why is something like this working: System::Boolean^ bTest; bTest = true; AND What is the difference between the following: a) System::Boolean bTest; b) System::Boolean^ bTest; c) System::Boolean^ bTest = gcnew System::Boolean 3) Classes seem to behave differently, too. If you create a managed class like ref class oAnObject { }; You can call certain member functions, which do not refer to a member variable (aparrently because this is a null reference or null pointer or whatever - see, I'm confused ;-)) without creating an instance in memory meaning: oAnObject::SomeFunction(void); Does work! 4) At last, I have a question about WinForms and the Data binding capability. This one is great, too, but: I can bind propertys of classes, without creating an instance of them and without having them declared as static. Well... okay, now I want to create an instance of the very same class (say for saving a textbox's content history or whatever) and copy the contents of the data bindings... how? Well, you see, I need a little help here. And sorry for my "newbish" questions. Thanks, ZMaster
Advertisement
Unsure about the first two questions as I am from a c# background and have never come across this.

Question 3, Do you mean static methods?

Question 4, Are you wanting to copy the data in one class to another or the contents of the databound control to another class?
MSDN - ^ (Handle to Object on Managed Heap)

It seems to be a specialized pointer for managed c++. It seems to be for pointing to objects on the managed heap. It looks like it is meant for having a little more control than the standard c++ pointer.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Quote:Original post by Rattrap
MSDN - ^ (Handle to Object on Managed Heap)

It seems to be a specialized pointer for managed c++. It seems to be for pointing to objects on the managed heap. It looks like it is meant for having a little more control than the standard c++ pointer.


Thank you for the link, but I already knew that article.
Questions #3 and #4 are clear now, I also found out that .NET 2 supports lists in datasource objects bound to controls, which makes #4 obsolete because I can use these lists, now.

However, questions #1 and #2 still remain. Because, when the managed reference is just a tracked pointer to data on the managed heap, I still wonder why I can do this:
System::Boolean^ bTest = true;
If bTest is just a pointer to the heap I would change the address instead of the value of bTest.

Why do I HAVE to declare System::String^ sTest = "Test"; as an object on the managed heap? (The declaration without the ^ wouldn't work, while it works for most other types).
I'm not an expert in this, but I think the reason you can't create a string object on the native heap is related to the way strings in .net work. They have a table that contains all the constant strings in the program (possibly also strings that arn't constant at compile time). Anyway, the table is possibly on the managed heap, there for you can't have a non managed pointer pointing to it.
Remember that the .net strings are immutable objects? Every change to them sets them to point somewhere else, the new object will be created on the managed heap, and therefor you must have a managed pointer pointing to it.
Thats my guess anyway, no gaurantees
I can tackle 1 and 2:

1: .Net object live on the managed heap. This allows it to move, resize, and delete objects at will. This is why you dont need to call delete.

2: (This is all AFAIK) Because of the tricks of the MSIL compiler. MSIL is kind of like the executables of .Net, which get Just-In-Time compiled to regular exes(like from c++ and other non-.net code.) The MSIL compiler can sort through code like that and change the reference assignment to assigning to the object being referenced.

The other code is also because of the MSIL compiler changing all those examples down to one peice of code.
I program in my sleep,but when I sleep I use the partition in my head that doesnt have g++ or the .net library, so im kinda screwed.
Quote:Original post by IMG25
Remember that the .net strings are immutable objects? Every change to them sets them to point somewhere else, the new object will be created on the managed heap, and therefor you must have a managed pointer pointing to it.
Thats my guess anyway, no gaurantees

Thanks. That sounds plausible.
Okay, here it goes.

^ is a handle to a garbage collected object rather than a pointer to memory. This allows the garbage collector to move objects around to defrag the heap.
Ref classes MUST live on the heap. System::String is a ref class. You must gcnew it, you can not put it onto the stack.
Value classes are able to live on the stack or the heap. However, value classes can not had destructors or operator overloads.

Ref classes are specially designed in 2005 to allow operator overloading through handles. You can add, subtract, multiply, bitshift, whatever on handles and it will affect the object wit refers to rather than the handle itself. The same can not be said about pointers. The reason for this is that the handle points to an object not memory! You can't alter the handle at all except assigning a different object to it. In fact, handles don't have an integer representation (in the high level languages) like pointers do. You can't "add 1" to get the next object in memory. Therefore, it makes perfect sense to allow operator overloading through handles.

I want you to do a little experiment:
ref class Test{public:    int held;};void main(){    System::String^ a = "test";    System::String^ b = a;    b += "2";    System::Console::WriteLine(a);//Prints "Test"    Test^ c = gcnew Test();    c->held = 5;    Test^ d = c;    d->held += 5;    System::Console::WriteLine(c);//Prints "10"}


[Edited by - Erzengeldeslichtes on December 7, 2005 8:47:11 AM]
----Erzengel des Lichtes光の大天使Archangel of LightEverything has a use. You must know that use, and when to properly use the effects.♀≈♂?
@Erzengeldeslichtes:
Thanks! Your description makes things much clearer!

This topic is closed to new replies.

Advertisement