Figure 2 Overloadable .NET Operators
Operator | Function Name | Example | Unary | Unary Addition (+) | op_UnaryPlus | b = +a | Unary Negation (-) | op_UnaryNegation | b = -a | Logical Not (!) | op_LogicalNot | b = !a | One's Complement (~) | op_OnesComplement | b = ~a | Increment (++) | op_Increment | b++ | Decrement (--) | op_Decrement | b-- | Logical True (true)* | op_True | if ( b ) | Logical False (false)* | op_False | if ( b ) | Binary | Addition (+) | op_Addition | b + a | Subtraction (-) | op_Subtraction | b - a | Multiplication (*) | op_Multiply | b * a | Division (/) | op_Division | b / a | Modulus (%) | op_Modulus | b % a | Bitwise And (&) | op_BitwiseAnd | b & a | Bitwise Or (|) | op_BitwiseOr | b | a | Bitwise/Logical XOR (^) | op_ExclusiveOr | b ^ a | Left Shift (<<) | op_LeftShift | b << a | Right Shift (>>) | op_RightShift | b >> a | Equality (==)* | op_Equality | b == a | Inequality (!=)* | op_Inequality | b != a | Greater than (>)* | op_GreaterThan | b > a | Less than (<)* | op_LessThan | b < a | Greater than or equal (>=)* | op_GreaterThaOrEqual | b >= a | Less than or equal (<=)* | op_LessThanOrEqual | b <= a | Figure 3 Using GCHandle #using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma managed
class AppDomainWrapper
{
private:
int m_handle;
public:
AppDomainWrapper() {
AppDomain* d = AppDomain::Current;
m_handle = (GCHandle::op_Explicit(GCHandle::Alloc(d))).ToInt32();
}
~AppDomainWrapper() {
(GCHandle::op_Explicit(m_handle)).Free();
}
// more functions here...
void PrintBaseDir() {
AppDomain* domain = __try_cast<AppDomain*>(
(GCHandle::op_Explicit(m_handle)).Target);
Console::WriteLine ( S"AppDomain Base Directory: {0}",
domain->BaseDirectory );
}
};
#pragma unmanaged
int main() {
AppDomainWrapper w;
w.PrintBaseDir();
return 0;
}
Figure 4 Using gcroot #using <mscorlib.dll>
#include <gcroot.h>
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma managed
class AppDomainWrapper
{
private:
gcroot<AppDomain*> m_domain;
public:
AppDomainWrapper() {
m_domain = AppDomain::CurrentDomain;
}
~AppDomainWrapper() {
}
// more functions here...
void PrintBaseDir() {
Console::WriteLine ( S"AppDomain Base Directory: {0}",
m_domain->BaseDirectory );
}
};
#pragma unmanaged
int main() {
AppDomainWrapper w;
w.PrintBaseDir();
return 0;
}
Figure 5 Marshaling Strings void MarshalString ( System::String* s, std::string& os )
{
using namespace System::Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
void MarshalString ( System::String* s, std::wstring& os )
{
using namespace System::Runtime::InteropServices;
const wchar_t* chars =
(const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
Figure 6 auto_dispose Template template <typename T>
class auto_dispose
{
private:
gcroot<T*> m_obj;
public:
auto_dispose ( T* o = 0 ) : m_obj(o) {}
~auto_dispose() {
if ( m_obj != 0 ) {
using namespace System;
// make sure T implements IDisposable
IDisposable* disposable = static_cast<IDisposable*>((T*)m_obj);
disposable->Dispose();
m_obj = 0;
}
}
auto_dispose& operator= ( T* o ) {
if ( m_obj != o ) m_obj = o;
return *this;
}
T* operator-> () const { return m_obj; }
private:
// hide copy constructor and assignment
// otherwise, this won't work!
auto_dispose ( const auto_dispose& );
auto_dispose& operator= ( const auto_dispose& );
};
|