| 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.
Managed Extensions for C++: __sealed keyword
This topic applies only to version 1 of Managed Extensions for C++. This syntax should only be used to maintain version 1 code. Use sealed for the equivalent functionality in the new syntax. This keyword prevents a method from being overridden or a class from being a base class.
The __sealed keyword specifies that a class method cannot be overridden or that a class cannot be a base class. When using the __sealed keyword, keep the following points in mind:
When a class (or struct) is marked with __sealed, the class cannot be used as a base class. For example:
|
The __sealed keyword is not allowed when used with the __abstract keyword. In the following example, a sealed virtual method (f) is declared. The function is then overridden in main(), causing a compiler error:
// keyword __sealed
// compile with: /clr:oldSyntax
#using <mscorlib.dll>
extern "C" int printf_s(const char*, ...);
__gc struct I
{
__sealed virtual void f()
{
printf_s("I::f()\n");
}
virtual void g()
{
printf_s("I::g()\n");
}
};
__gc struct A : I
{
void f() // C3248 sealed function
{
printf_s("A::f()\n");
}
void g()
{
printf_s("A::g()\n");
}
};
int main()
{
A* pA = new A;
pA->f();
pA->g();
}
The following is a sample output seen in the Visual C++ IDE's Output window.
1>------ Build started: Project: testprog2, Configuration: Debug Win32 ------
1>Compiling...
1>testprog2.cpp
1>.\testprog2.cpp(21) : error C3248: 'I::f': function declared as '__sealed' cannot be overridden by 'A::f'
1> .\testprog2.cpp(9) : see declaration of 'I::f'
1>Build log was saved at "file://f:\vc2005project\testprog2\testprog2\Debug\BuildLog.htm"
1>testprog2 - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The new C++ sealed keyword
sealed is a context sensitive keyword that can indicate:
A virtual member cannot be overridden.
A type cannot be used as a base type.
sealed is also valid when compiling for native targets (without /clr). You can detect at compile time if a type is sealed with __is_sealed (type). sealed is a context-sensitive keyword. This sample shows the effect of sealed on a virtual member:
// sealed keyword
// compile with: /clr
interface struct I1 {
virtual void f();
virtual void g();
};
ref class X : I1 {
public:
virtual void f() { System::Console::WriteLine("X::f override of I1::f"); }
virtual void g() sealed { System::Console::WriteLine("X::f override of I1::g"); }
};
ref class Y : public X {
public:
virtual void f() override { System::Console::WriteLine("Y::f override of I1::f"); }
/*
// the following override generates a compiler error
virtual void g() override {
System::Console::WriteLine("Y::g override of I1::g");
}
*/
};
int main() {
I1 ^ MyI = gcnew X;
MyI -> f();
MyI -> g();
I1 ^ MyI2 = gcnew Y;
MyI2 -> f();
}
Output:

The following sample shows how to mark a class as sealed:
// sealed keyword
// compile with: /clr
interface struct I1 {
virtual void f();
};
ref class X sealed : I1 {
public:
virtual void f() override {}
};
ref class Y : public X { // C3246 base class X is sealed
public:
virtual void f() override {}
};
The following is the output sample seen in the Output window.
1>------ Build started: Project: cplus, Configuration: Debug Win32 ------
1>Compiling...
1>cplusrc.cpp
1>.\cplusrc.cpp(9) : warning C4490: 'override' : incorrect use of override specifier; 'X::f' does not match a base ref class method
1> 'new' or 'override' are only allowed when a matching base method from a ref class exists
1> Matching base method 'I1::f' is from an interface class (not a ref class)
1>.\cplusrc.cpp(12) : error C3246: 'Y' : cannot inherit from 'X' as it has been declared as 'sealed'
1> .\cplusrc.cpp(7) : see declaration of 'X'
1>Build log was saved at "file://f:\vc2005project\cplus\cplus\Debug\BuildLog.htm"
1>cplus - 1 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The new C++ abstract keyword
abstract is a context sensitive keyword that can indicate:
A member can only be defined in a derived type.
A type cannot be instantiated (can only act as a base type).
Marking a function abstract is the same as making it a pure virtual function. Making a member function abstract causes the enclosing class to also be marked abstract. abstract is also valid when compiling for native targets (without /clr). You can detect at compile time if a type is abstract with __is_abstract(type). abstract is a context-sensitive keyword. The following sample will generate an error because class X is marked abstract.
// abstract keyword
// compile with: /clr
ref class X abstract
{
public:
virtual void f() {}
};
int main()
{
X ^ MyX = gcnew X; // C3622 cannot instantiate abstract class
}
The following is an output sample seen in the Output window.
1>------ Build started: Project: cplus, Configuration: Debug Win32 ------
1>Compiling...
1>cplusrc.cpp
1>.\cplusrc.cpp(9) : error C3622: 'X': a class declared as 'abstract' cannot be instantiated
1> .\cplusrc.cpp(3) : see declaration of 'X'
1>Build log was saved at "file://f:\vc2005project\cplus\cplus\Debug\BuildLog.htm"
1>cplus - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The following sample shows that the compiler will generate an error because a native class is marked abstract, when compiled with /clr.
// abstract keyword
class X abstract
{
public:
virtual void f() {}
};
int main()
{
X * MyX = new X; // C3622 error expected
}
The following is the output sample seen in the Output window.
1>------ Build started: Project: cplus, Configuration: Debug Win32 ------
1>Compiling...
1>cplusrc.cpp
1>.\cplusrc.cpp(8) : error C3622: 'X': a class declared as 'abstract' cannot be instantiated
1> .\cplusrc.cpp(2) : see declaration of 'X'
1>Build log was saved at "file://f:\vc2005project\cplus\cplus\Debug\BuildLog.htm"
1>cplus - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
The following sample will generate an error because function f is marked abstract.
// abstract keyword
// compile with: /clr
ref class X {
public:
virtual void f() abstract {} // C3634 error expected
virtual void g() = 0 {} // C3634 error expected
};
The following is the output sample seen in the Output window.
1>------ Build started: Project: cplus, Configuration: Debug Win32 ------
1>Compiling...
1>cplusrc.cpp
1>.\cplusrc.cpp(5) : error C3634: 'void X::f(void)' : cannot define an abstract method of a managed class
1>.\cplusrc.cpp(6) : error C3634: 'void X::g(void)' : cannot define an abstract method of a managed class
1>.\cplusrc.cpp(3) : warning C4570: 'X' : is not explicitly declared as abstract but has abstract functions
1> 'void X::f(void)' : is abstract
1> .\cplusrc.cpp(5) : see declaration of 'X::f'
1> 'void X::g(void)' : is abstract
1> .\cplusrc.cpp(6) : see declaration of 'X::g'
1>Build log was saved at "file://f:\vc2005project\cplus\cplus\Debug\BuildLog.htm"
1>cplus - 2 error(s), 1 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========