beginthreadex said:
Persons that have been developing in VC++ for many years might run into the
same issues that I do with my teams. If MS knows that the classes are
collected then the syntax should not matter. There should be no reason for
^ instead of * or % instead of &. Just stick to what's already trained into
people so we don't need to keep rewritting things but use all the tools.
Unfortunately there are substantial differences between the native and
the managed OOP paradigm. The .NET framework doesn't support global
variables and functions at all, it only knows methods and properties.
Although C++/CLI has stack syntax, the framework only supports pointer
(handle) syntax for ref classes, and value classes are severely limited.
In the managed world, there's no concept for const (in particular,
global constants, const member functions), which is IMHO is a very big
problem, but this is what we have. Heck, even the concept of destructors
doesn't exist in the managed world, and C++/CLI destructors are not 100%
compatible with the standard ones. The concept of default argument
doesn't exist either. Should I go on? Virtual functions must be
explicitly declared "override" if they override an existing one. There
is no operator overloading either.
On the other hand, native C++ doesn't have the concept of properties,
delegates, events, and most importantly, the concept of public and
private classes. Every class that's #include'ed is public, what's not in
the headers is private.
Even though it sounds nice in theory to be able to share the same code
base between the native and the managed worlds, it's almost never
technically possible. You can't write anything more than trivial that
you could share between native C++ and managed C++. I agree that the old
MC++ syntax looked like you could share trivial code between the two,
but I don't think it was practical in real-world applications or
libraries. You would have to be very careful to use only that narrow
common feature set that both worlds have, and even then you have to deal
with the class visibility issue. "public class" doesn't compile under
std C++, but a simple "class" means private in old MC++, which is not
what you want. The old MC++ syntax may give you a false sense of
security that you can theoretically write code for both worlds, when in
practice it almost never happens.
I question myself if it would have made sense to create C++/CLI so that
you could share code between the two world. When you could really write
it once and compile standard native C++ code into pure managed
assemblies. Such as disregarding the const keyword in managed mode.
Setting up the default class visibility using a #pragma class public, or
something similar. Automatically inserting the "override" keyword for
virtual methods that override existing ones. Keeping the * and & symbols
for managed handles and references. Automatically substituting static
const members with read-only properties. Automatically substituting
default arguments with function overriding for .NET. Automatically
substitute getter and setter functions with properties. And so on and so
forth. But C++ is a low-level language, and these hidden translations in
the background would certainly mean losing control. You still wouldn't
be able to do everything, you'd still need to #ifdef a whole bunch of
lines. You still wouldn't be able to use events in native C++ the exact
same way as delegates work in .NET, even though similar concepts
(boost::function) now exist in standard C++. It's impossible to
translate every unmanaged C++ code to .NET anyway.
Quite frankly, I don't think this was their goal with C++/CLI. They
wanted a language where you
1) have low-level, but full support for almost every .NET framework
feature, with a language as similar to C++ as possible
2) can freely intermix managed and unmanaged code, and for that it was a
very good idea to introduce the ^ and % symbols. It's way less confusing
than __gc * and __nogc *. I love that T ^ is managed and U * is
unmanaged, and I can tell that in an instant.
But I'm hearing you, sometimes it would be very nice to compile native
C++ code into pure managed, without having to rewriting a single line,
even if there are severe restrictions with that. Maybe someone will
write a standard C++ to C++/CLI code converter. After all, Borland
created a mechanism for automatically generating a C++ header file from
a Pascal input, and with few limitations it works perfectly (only Pascal
is trivial to parse, C++ is far from it). I can imagine an automated
native to managed converter would work with restrictions, so we could
write once and reuse the code twice. I could imagine converting
boost::shared_ptr<T> to T^, and boost::function to delegates, and so on.
The question is how much market it has, because it's quite some work to
write such a compiler.
In practice, when you program for .NET you use framework types and
functions, such as Drawing::Color, Rectangle, String, and .NET
collections. How far are you willing to go with the automatic type
substitution? I don't think it's feasable to really write your code once
and reuse it for native C++ and .NET at the same time. You're pretty
much forced to rewrite it, or to wrap unmanaged code into managed classes.
Tom