I'm been curious about the declaration syntax of Collections::Generic::Dictionary class in C++/CLI.
Normally we declare a reference in开发者_JS百科 a class and initialize it:
public ref class CDemo {
private: ClassA ^ m_InstanceA;
// Why the absence of '^'.
private: Dictionary<int, int> m_Dic;
CDemo() :
m_InstanceA(gcnew ClassA()),
m_Dic(gcnew Dictionary<int, int>())
{...}
};
Could someone explains please why should the '^' absent there?
What's more, if I were to use the dictionary above as a TValue of another dictionary, I have to declare it like this:
Dictionary<T, Dictionary<T, T>^ > m_Dic; // A '^' in the TValue parameter, which is
// normal, but same question as above,
// I don't have to declare m_Dic as ^ ?
Thanks.
This is not specific to Dictionary
. This syntax is a way to help map C++ semantics onto managed types. In general:
ref class A
{
ReferenceType m_obj;
};
is roughly equivalent to
class A : IDisposable
{
private ReferenceType m_obj;
void Dispose() { m_obj.Dispose(); }
}
in C# if ReferenceType
implements IDisposable
. It is perfectly possible to write
ref class A
{
ReferenceType^ m_obj;
};
This does not have the implicit IDisposable
support. The other difference is that you can return a ReferenceType^
from a method, this is not supported with just plain ReferenceType
. For example:
ref class A
{
ReferenceType^ m_obj;
ReferenceType^ GetIt() { return m_obj; }
};
will compile,
ref class A
{
ReferenceType m_obj;
ReferenceType GetIt() { return m_obj; } // won't compile
ReferenceType^ OtherGetIt() { return m_obj; } // neither will this
};
A similar distinction is provided for automatic (stack variables)
ReferenceType local;
local.Stuff();
is desugared by the compiler to
try {
ReferenceType^ local = gcnew ReferenceType();
local->Stuff();
} finally {
delete local; // invokes Dispose() (~ReferenceType)
}
These features bring the familiar idiom of RAII to C++/CLI with managed types.
EDIT:
Yes, the Dispose method of IDisposable is analogous to a C++ destructor. If ReferenceType
doesn't implement IDisposable
(doesn't have a dtor), and it is the only member, A
will also not implement IDisposable
(not have an implicit dtor). In C++/CLI you implement IDisposable
by providing a dtor (for managed types).
精彩评论