您如何处理 C++ 中的“无法实例化抽象类”错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11833905/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you handle a "cannot instantiate abstract class" error in C++?
提问by xarzu
How do you handle a "cannot instantiate abstract class" error in C++? I have looked at some of the similar errors here and none of them seem to be exactly the same or problem that I am having. But, then again, I will admit that there are several to go over. Here is the compile error:
您如何处理 C++ 中的“无法实例化抽象类”错误?我在这里查看了一些类似的错误,但似乎没有一个与我遇到的完全相同或有问题。但是,话又说回来,我承认有几个要讨论的。这是编译错误:
This leads me to this page: http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(C2259);k(VS.ERRORLIST)&rd=trueCompile Error C2259 is from a C++ program but the page calls the abstract class an "interface":
这将我带到此页面:http: //msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(C2259);k(VS.ERRORLIST)&rd=true 编译错误 C2259 来自C ++程序,但页面调用抽象类的“接口”:
Whenever you derive from an interface and implement the interface methods in the derived class with access permissions other than public, you may receive C2259. This occurs because the compiler expects the interface methods implemented in the derived class to have public access. When you implement the member functions for an interface with more restrictive access permissions, the compiler does not consider them to be implementations for the interface methods defined in the interface, which in turn makes the derived class an abstract class.
There are two possible workarounds for the problem:
Make the access permissions public for the implemented methods.
Use the scope resolution operator for the interface methods implemented in the derived class to qualify the implemented method name with the name of the interface.
每当您从接口派生并在派生类中使用公共以外的访问权限实现接口方法时,您可能会收到 C2259。发生这种情况是因为编译器希望派生类中实现的接口方法具有公共访问权限。当您为具有更严格访问权限的接口实现成员函数时,编译器不会将它们视为接口中定义的接口方法的实现,从而使派生类成为抽象类。
该问题有两种可能的解决方法:
公开已实现方法的访问权限。
对派生类中实现的接口方法使用作用域解析运算符,用接口名称限定实现的方法名称。
The bad news is that I have already made all of the methods public in the class:
坏消息是我已经在类中公开了所有方法:
class AmbientOccluder: public Light {
public:
AmbientOccluder(void);
回答by juanchopanza
The error means there are some methods of the class that aren't implemented. You cannot instantiate such a class, so there isn't anything you can do, other than implement allof the methods of the class.
错误意味着有未实现的一些类的方法。您无法实例化这样的类,因此除了实现类的所有方法之外,您无能为力。
On the other hand, a common pattern is to instantiate a concrete class and assign it to a pointer of an abstrate base class:
另一方面,一种常见的模式是实例化一个具体类并将其分配给一个抽象基类的指针:
class Abstract { /* stuff */ 4};
class Derived : virtual public Abstract { /* implement Abstract's methods */ };
Abstract* pAbs = new Derived; // OK
Just an aside, to avoid memory management issues with the above line, you could consider using a smart pointer, such as an `std::unique_ptr:
顺便说一句,为了避免上述行的内存管理问题,您可以考虑使用智能指针,例如`std::unique_ptr:
std::unique_ptr<Abstract> pAbs(new Derived);
回答by Olivier Dagenais
Visual Studio's Error Listpane only shows you the first line of the error. Invoke View
>Output
and I bet you'll see something like:
Visual Studio 的错误列表窗格仅显示错误的第一行。调用View
>Output
我敢打赌你会看到类似的东西:
c:\path\to\your\code.cpp(42): error C2259: 'AmbientOccluder' : cannot instantiate abstract class
due to following members:
'ULONG MysteryUnimplementedMethod(void)' : is abstract
c:\path\to\some\include.h(8) : see declaration of 'MysteryUnimplementedMethod'
回答by Code-Apprentice
An abstract class cannot be instantiated by definition. In order to use this class, you must create a concrete subclass which implements all virtual functions of the class. In this case, you most likely have not implemented all the virtual functions declared in Light
. This means that AmbientOccluder
defaults to an abstract class. For us to further help you, you should include the details of the Light
class.
抽象类不能通过定义实例化。为了使用这个类,你必须创建一个具体的子类来实现该类的所有虚函数。在这种情况下,您很可能没有实现Light
. 这意味着AmbientOccluder
默认为抽象类。为了让我们进一步帮助您,您应该包括Light
课程的详细信息。
回答by bazz
Provide implementation for any pure virtual functions that the class has.
为类具有的任何纯虚函数提供实现。
回答by vaibhav gupta
Why can't we create Object of Abstract Class ? When we create a pure virtual function in Abstract class, we reserve a slot for a function in the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the VTABLE will be incomplete. As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an errror message whenever you try to do so.
为什么我们不能创建抽象类的对象?当我们在 Abstract 类中创建一个纯虚函数时,我们在 VTABLE 中为函数保留了一个槽(在上一个主题中研究过),但没有在该槽中放置任何地址。因此 VTABLE 将是不完整的。由于抽象类的 VTABLE 不完整,因此编译器不会允许为此类创建对象,并且每当您尝试这样做时都会显示错误消息。
Pure Virtual definitions
纯虚拟定义
Pure Virtual functions can be given a small definition in the Abstract class, which you want all the derived classes to have. Still you cannot create object of Abstract class. Also, the Pure Virtual function must be defined outside the class definition. If you will define it inside the class definition, complier will give an error. Inline pure virtual definition is Illegal.
纯虚函数可以在抽象类中给出一个小的定义,您希望所有派生类都具有它。你仍然不能创建抽象类的对象。此外,必须在类定义之外定义纯虚函数。如果在类定义中定义,编译器会报错。内联纯虚拟定义是非法的。
回答by Narasimha Nallamsetty
I have answered this question here..Covariant virtual functions return type problem
我在这里回答了这个问题..协变虚函数返回类型问题
See if it helps for some one.
看看它是否对某人有帮助。
回答by CLIFFORD P Y
In my case i declared a function in COM Control .idl
file like
就我而言,我在 COM 控制.idl
文件中声明了一个函数,例如
[id(1)] HRESULT MyMethod([in]INT param);
but not declared in my interface .h
file like this
但没有.h
像这样在我的接口文件中声明
STDMETHOD(MyMethod)(INT param);
Problem solved by adding above line into my interface .h file
通过将上述行添加到我的界面 .h 文件中解决了问题
this might help some one .
这可能对某些人有所帮助。