The Value of a Value Class
A reader questions the nature of the value type when he writes,
Sender: Slawomir Lisznianski
1) Lack of support for SMFs makes value classes unnatural to use. An example in the C++/CLI spec at page 33 is incorrect, as it uses constructors with value classes. In fact, quite a few value class examples in the specification contradict with paragraph 21.4.1.
SMF, for the uninitiated, means special member functions, and in this case refers to the constraint on a value class that it cannot declare a default constructor, copy constructor, copy assignment operator, or destructor.
Mechanically, the reason these special member functions are not supported, I am told, is because there exists conditions during run-time in which it is not possible for the compiler to insert the appropriate invocations, and thus it is not possible to guarantee the semantics associated with these member functions. And so their support has been withdrawn completely. I suspect that the examples were written before the withdrawal of the default constructor, and the authors of the spec simply overlooked removing them.
There are a number of negative responses one can have to this: Disbelief, disgust, savage anger are a few that come to mind.
Another way of looking at this is to consider the why and when these special member functions are not required. We do not need a copy constructor nor a copy operator when the aggregate type supports bitwise copy. Similarly, we do not need a destructor when the state of the aggregate type exhibits value semantics. Finally, if the runtime zeros out all state by default, then we do not require a default constructor. (In C++, primitive data types are not automatically zeroed out, and so most of our default constructor use – but granted, not all – is used to put the object in an uninitialized state.)
That is, a value type in the philosophy of the CLI unified type system is a blitable entity with no internal plumbing, so to speak. That is all it naturally supports.
You put a pointer in it, you got troubles – there are no special member functions to provide deep copy semantics or to free the resource addressed prior to the end of its lifetime. Let's not even consider attempting to declare complex member types. That's not what you do with value classes.
I will claim that they are not unnatural. What is unnatural, but understandable presuming that you have a C++ background, are the sophisticated uses you think to put these rather unsophisticated types. When you think value class, think integer. Then things will begin to click for you.
I will address your second question in a subsequent blog: So what's the rationale for trackable references ... ?