C++ vs C++/CX (Part 1) Testing basic structs

I have been looking into the difference between native C++ and Microsoft’s extension of C++ called C++/CX. C++/CX is similar but very much revised version of C++/CLI (along with other Microsoft variations of C++). CX sees very heavy use in their Metro C++ based apps. It looks like CX is just a compiler extension and thus you can compile normal C++ along with CX extensions. This is an extremely nice feature since you can compile cross platform code into your Windows apps. 

Before I start, I would like to point out that CX is Microsoft only. In other words, you can only compile CX code using the Visual C++ compiler. You cannot compile any CX code with any other compiler and thus the portability of your code is limited to Windows (8?) only.


Getting Started

First thing first; I setup a test for a stack allocated struct. I have duplicated a base struct, one in normal C++ and the other in the CX variation.

I had some issues with the CX compiler picking up the CX extensions on first go. If you get this issue, I solved it by adding

</p><p>#include "App.g.h"</p><p>

compiling and then removing it. Ok, lets keep moving.

The two structs are as follows:

</p><p>//Managed<br />ref struct myStruct sealed<br />{<br />public:<br /> myStruct(int inputInt)<br /> {<br /> //You cannot do inline initialization it looks like<br /> this-&gt;testInt = inputInt;<br /> }</p><p>property int testInt;<br />};</p><p>//Non managed<br />struct myStruct2<br />{<br />public:<br /> myStruct2(int inputInt)<br /> : testInt(inputInt)<br /> {</p><p>}</p><p>int testInt;<br />};</p><p>

I added this into it’s own header file. I’ll let you create and name it yourself. Just remember to add it in wherever you need to use the code.


Ok, first I want to talk about the ref keyword. This keyword indicates that the class is part of the CX extension. It also indicates that the class is managed. Based on this it is the same as saying “class” in c#. Basically from what I understand this indicates that the class will go into the GC (garbage collector) heap. Any other examples I have seen seems to require that this keyword is added if the class belongs to the CX extension.


In my experimentation, the compiler began to demand that this keyword once I added a constructor. If I remove it, it throws a:

Error 1 error C2456: ‘myStruct’ an unsealed ref class cannot have a public visible constructor. Seal the class, or specify constructor as ‘internal’, ‘protected private’ or ‘private’ instead.

From the MSDN documentation, sealed indicates that:

sealed is a context-sensitive keyword for ref classes that indicates that a virtual member cannot be overridden, or that a type cannot be used as a base type.

This is unlike normal C++. It seems like CX requires that if you expose the constructor publicly, it is the end of the inheritance. This is similar to the final keyword introduces in the C++ 11 specification. At this current time I am not sure what this means as far as the CX implementation, but I am sure I will discover why they made this design choice shortly.


This is a direct borrow from C#. A property will will create something similar to:

</p><p>int myInt { get; set; }</p><p>

in C#. Member variables cannot be public in CX, so one may use this to condense the getter/setter functions. CX seems to have strict rules about encapsulation. You can get around this by making member variables private and providing your own getter and/or setter functions.

Direct Initialization

I might be using the term incorrectly. However, in C++ you can initialize variables inside the constructor using the following method

</p><p>myStruct2(int inputInt)<br />: testInt(inputInt)</p><p>

This will initialize the variables before entering the constructor body. I was not able to do this in the CX version. Something tells me that this is because the member variable is a property. However, if I change make this into a normal variable and make it private, the direct initialization becomes possible.

</p><p>myStruct(int inputInt)<br /> : testInt(inputInt)<br /> {</p><p>}</p><p>private:<br /> int testInt;</p><p>

This calls for creating a separate accessor to your member variables as member variables cannot be public. 

Stack Allocation

Just like normal C++, you can stack allocate your structs/classes. To test, I created the following code:

</p><p>myStruct str1(1);<br /> myStruct2 str2(2);</p><p>str1.testInt = str2.testInt;</p><p>

This is completely legal with CX. I added a destructor (see Destructor) to the struct and it is in fact called when the instance goes out of scope.


CX supports a destructor. However, it is not allowed to be public. This means that you cannot explicitly destroy objects. The destructor will be called when GC destroys the object. It is however, as mentioned before, possible to stack allocate CX objects. In this case, you can control destruction as it will be called when the owning function goes out of scope.


Closing Notes

It seems like CX is trying to find a middle ground between C++ and C# which is an interesting design choice. I will go as far as to say it is very likely that Microsoft is trying to appeal to both parties of programmers. However, both C++ and C# programmers will find this approach a bit frustrating. Both languages fore fill their own design approach which is not completely compatible with CX.

The biggest pitfall for C++ programmers seems to be the removal of real pointers. By putting CX objects into the GC heap, C++ programmers will find it somewhat frustrating as CX pointers represent C# references more than C/C++ pointers. The upside however, is that CX can by bypassed unless absolutely necessary.

On the other end C# programmers will have to put up with native C++ syntax and contentions. The Header/Implementation code setup is inherited from C++ (as this is still C++, not C#).

The biggest pit fall for both sides is that CX seems to have a tight syntax rule base. Neither language enforces such strict rules on public vs private elements. As someone who works in both languages, this is a bit frustrating.