You receive a "C2259" error code when a derived class has stricter access permissions for interface method implementations (814914)



The information in this article applies to:

  • Microsoft Visual C++ .NET (2003)
  • Microsoft Visual C++ 2005 Express Edition

SYMPTOMS

When you derive a class from an interface, and you implement the interface methods in the derived class with access permissions other than public, you may receive the following compiler error message:
error C2259: 'MyDerivedClass' : cannot instantiate abstract class due to following members 'void MyInterface::MyMethod(void)' : pure virtual function was not defined
abstract.cpp(5) : see declaration of 'MyInterface::MyMethod'
Note You can define the interface in Microsoft Visual C++ .NET or in Microsoft Visual C++ 2005 with the help of the __interface keyword.

Note In Visual C++ 2005, you receive the following messages:
warning C4570: 'MyDerivedClass' : is not explicitly declared as abstract but has abstract functions
error C2259: 'MyDerivedClass' : cannot instantiate abstract class

CAUSE

This problem occurs because the compiler expects the interface methods that are implemented in the derived class to have public access permissions. When you implement the member functions for an interface with more restrictive access permissions, the compiler does not interpret them as implementations for the interface methods that are defined in the interface. This behavior causes the derived class to change to an abstract class.

STATUS

This behavior is by design.

WORKAROUND

Use one of the following two methods to work around the problem:
  • Make the access permissions public for the implemented methods as follows:
    __gc class MyDerivedClass : public MyInterface
    {
    	public:
    	void MyMethod() {};
    };
  • Use the scope resolution operator for the interface methods that are implemented in the derived class to qualify the implemented method name with the name of the interface.

    Using the code that is listed in the first method for the derived class ( MyDerivedClass), change the code in the derived class as follows:
    __gc class MyDerivedClass : public MyInterface
    {
    	void MyInterface::MyMethod() {};
    };
    where MyInterface is defined as follows:
    public __gc __interface MyInterface
    {
    	void MyMethod();
    };

MORE INFORMATION

Steps to Reproduce the Behavior

  1. Paste the following code in Notepad, and then save the file as abstract.cpp:
    #using <mscorlib.dll>
    // In Visual C++ 2005, you should add "#include "stdafx.h"" here.
    
    public __gc __interface MyInterface
    {
    	void MyMethod();
    };
    
    __gc class MyDerivedClass : public MyInterface
    {
    	void MyMethod() {};
    };
    
    void main()
    {
    	MyDerivedClass *instance = new MyDerivedClass();
    }
    Note You must add the common language runtime support compiler option (/clr:oldSyntax) in Visual C++ 2005 to successfully compile this code sample. To do this, follow these steps:
    1. Click Project, and then click ProjectName Properties.

      Note ProjectName represents the name of the project.
    2. Expand Configuration Properties, and then click General.
    3. Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project setting on the right pane, click Apply, and then click OK.
    For more information about the common language runtime support compiler options, visit the following Microsoft Web site:

    /clr (Common Language Runtime Compilation)
    http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

  2. From the Microsoft Visual Studio .NET 2003 command prompt or the Microsoft Visual Studio 2005 command prompt, type the following command to compile the abstract.cpp file:
    cl /clr abstract.cpp
You receive the compiler error message that the "Symptoms" section describes.

Modification Type:MajorLast Reviewed:1/6/2006
Keywords:kbCompiler KB814914 kbAudDeveloper kbAudITPRO