< Old To New C++ .Net version 3 | Main | Old To New C++ .Net version 5 >


 

 

Early Stages of the C++ .Net 26

(From Managed Extensions for C++ to new C++ .NET Syntax)

 

 

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.

  1. The new C++ override keyword

  2. The new C++ new (new slot in vtable) keyword

  3. The new C++ novtable keyword

  4. The Managed Extensions for C++: __gc keyword

 

 

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.

// override keyword

// compile with: /clr /c

 

ref struct I1 {

   virtual void f();

};

 

ref struct X : public I1 {

   virtual void f() override {}

};

 

int main()

{

      return 0;

}

The following is a sample output seen from the Output window.

1>------ Build started: Project: cplus, Configuration: Debug Win32 ------

1>Compiling...

1>cplusrc.cpp

1>Linking...

1>cplusrc.obj : error LNK2020: unresolved token (06000001) I1::f

1>F:\vc2005project\cplus\Debug\cplus.exe : fatal error LNK1120: 1 unresolved externals

1>Build log was saved at "file://f:\vc2005project\cplus\cplus\Debug\BuildLog.htm"

1>cplus - 2 error(s), 0 warning(s)

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

 

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:

gcnew, overide, new, ref class keywords program 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).

 

// novtable keyword

#include <stdio.h>

 

struct __declspec(novtable) X { virtual void mf(); };

 

struct Y : public X {

   void mf() { printf_s("In Y\n"); }

};

 

int main()

{

   // X *pX = new X();

   // pX->mf();   // AV at runtime

   Y *pY = new Y();

   pY->mf();

}

 

Output:

__declspec, virtual, novtable, new keywords program output

 

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.

  1. __gc array-specifier

  2. __gc class-specifier

  3. __gc struct-specifier

  4. __gc interface-specifier

  5. __gc pointer-specifier

  6. __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:

new, __gc keywords program output

 

 

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7 | Part 8 | Part 9

 

 


< Old To New C++ .Net version 3 | Main | Old To New C++ .Net version 5 >