The code snippets used in this module if any are Visual C++ .Net 2003 dominated and if compiled using Visual C++ .Net 2005 you need to use the /clr:oldSyntax option). The following are the topics available in this module.
The new C++ override keyword
override indicates that a member of a managed type must override a base class or a base interface member. If there is no member to override, the compiler will generate an error. override is also valid when compiling for native targets (without /clr). override is a context-sensitive keyword.
The following is a sample output seen from the Output window.
|
The following sample shows that override can also be used in native compilations.
// override keyword
// compile with: /c
struct I1 {
virtual void f();
};
struct X : public I1 {
virtual void f() override {}
};
int main()
{
return 0;
}
The new C++ new (new slot in vtable) keyword
In a /clr compilation, new indicates that a virtual member will get a new slot in the vtable; that the function does not override a base class method. new causes the newslot modifier to be added to the IL for the function. The following sample shows the effect of new.
// new keyword
// compile with: /clr
ref class C {
public:
virtual void f() { System::Console::WriteLine("C::f() called"); }
virtual void g() { System::Console::WriteLine("C::g() called"); }
};
ref class D : public C {
public:
virtual void f() new { System::Console::WriteLine("D::f() called"); }
virtual void g() override { System::Console::WriteLine("D::g() called"); }
};
ref class E : public D {
public:
virtual void f() override { System::Console::WriteLine("E::f() called"); }
};
int main()
{
D^ d = gcnew D;
C^ c = gcnew D;
c->f(); // calls C::f
d->f(); // calls D::f
c->g(); // calls D::g
d->g(); // calls D::g
D ^ e = gcnew E;
e->f(); // calls E::f
}
Output:
The new C++ novtable keyword
This is a Microsoft Specific. This is a __declspec extended attribute. This form of __declspec can be applied to any class declaration, but should only be applied to pure interface classes, that is, classes that will never be instantiated on their own. The __declspec stops the compiler from generating code to initialize the vfptr in the constructor(s) and destructor of the class. In many cases, this removes the only references to the vtable that are associated with the class and, thus, the linker will remove it. Using this form of __declspec can result in a significant reduction in code size. If you attempt to instantiate a class marked with novtable and then access a class member, you will receive an access violation (AV).
|
The Managed Extensions for C++: __gc keyword
This should applies only to version 1 of Managed Extensions for C++. This syntax should only be used to maintain version 1 code. This keyword declares a __gc type. The following are the syntaxes.
__gc array-specifier
__gc class-specifier
__gc struct-specifier
__gc interface-specifier
__gc pointer-specifier
__gc new
A __gc type is a C++ language extension that simplifies .NET Framework programming by providing features such as interoperability and garbage collection. Every member function of an abstract __gc class must be defined unless the member function is pure virtual. In Managed Extensions for C++, the equivalents to a C# class and a C# struct are as follows:
Managed Extensions for C++ | C# |
__gc struct or __gc class | class |
__value struct or __value class | struct |
Table 3 |
In the following example, a managed class (X) is declared with a public data member, which is manipulated through a managed pointer:
// keyword __gc
// compile with: /clr:oldSyntax
#using <mscorlib.dll>
using namespace System;
__gc class X
{
public:
int i;
int ReturnInt() { return 5; }
};
int main()
{
// X is a __gc class, so px is a __gc pointer
X* px;
px = new X; // creates a managed object of type X
Console::Write("px->i = ");
Console::WriteLine(px->i);
px->i = 4; // modifies X::i through px
Console::Write("px->i = ");
Console::WriteLine(px->i);
int n = px->ReturnInt(); // calls X::ReturnInt through px
Console::Write("px->ReturnInt() = ");
Console::WriteLine(n);
}
Output: