34

如何处理 C++ 中的“无法实例化抽象类”错误?我在这里查看了一些类似的错误,但它们似乎都不是我遇到的完全相同或问题。但是,话又说回来,我承认有几个要过去。这是编译错误:

[IMG]http://i67.photobucket.com/albums/h292/Athono/cannotinstantiateabstractclass.png[/IMG]

这将我带到此页面: http: //msdn.microsoft.com/query/dev10.query ?appId=Dev10IDEF1&l=EN-US&k=k(C2259);k(VS.ERRORLIST)&rd=true 编译错误 C2259 来自一个 C++ 程序,但页面将抽象类称为“接口”:

每当您从接口派生并在派生类中以公共以外的访问权限实现接口方法时,您可能会收到 C2259。发生这种情况是因为编译器希望派生类中实现的接口方法具有公共访问权限。当您为具有更严格访问权限的接口实现成员函数时,编译器不会将它们视为接口中定义的接口方法的实现,从而使派生类成为抽象类。

该问题有两种可能的解决方法:

为实现的方法公开访问权限。

对派生类中实现的接口方法使用范围解析运算符,以用接口名称限定实现的方法名称。

坏消息是我已经在类中公开了所有方法:

class AmbientOccluder: public Light {
    public:

        AmbientOccluder(void); 
4

8 回答 8

49

该错误意味着该类的某些方法未实现。您无法实例化这样的类,因此除了实现该类的所有方法之外,您无能为力。

另一方面,一种常见的模式是实例化一个具体类并将其分配给抽象基类的指针:

class Abstract { /* stuff */ 4};
class Derived : virtual public Abstract { /* implement Abstract's methods */ };

Abstract* pAbs = new Derived; // OK

顺便说一句,为避免上述行的内存管理问题,您可以考虑使用智能指针,例如std::unique_ptr

std::unique_ptr<Abstract> pAbs(new Derived);
于 2012-08-06T18:36:43.553 回答
38

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'
于 2013-06-26T02:14:52.860 回答
11

抽象类不能按定义实例化。为了使用这个类,你必须创建一个具体的子类来实现该类的所有虚函数。在这种情况下,您很可能没有实现Light. 这意味着AmbientOccluder默认为抽象类。为了让我们进一步帮助您,您应该包括Light课程的详细信息。

于 2012-08-06T18:39:05.550 回答
4

为类拥有的任何纯虚函数提供实现。

于 2012-08-06T18:39:28.640 回答
1

为什么我们不能创建抽象类的对象?当我们在抽象类中创建一个纯虚函数时,我们在 VTABLE 中为函数保留了一个槽(在上一个主题中研究过),但没有在该槽中放置任何地址。因此 VTABLE 将是不完整的。由于抽象类的 VTABLE 不完整,因此编译器不会允许为此类创建对象,并且在您尝试这样做时会显示错误消息。

纯虚拟定义

纯虚函数可以在抽象类中给出一个小的定义,您希望所有派生类都具有该定义。你仍然不能创建抽象类的对象。此外,纯虚函数必须在类定义之外定义。如果你在类定义中定义它,编译器会报错。内联纯虚定义是非法的。

于 2013-10-16T13:16:01.647 回答
0

我在这里回答了这个问题。协变虚函数返回类型问题

看看它是否对某人有帮助。

于 2015-01-07T06:40:09.797 回答
0

如果有人从函数中收到此错误,请尝试在参数中使用对抽象类的引用。

void something(Abstract bruh){
}

void something(Abstract& bruh){
}

不能构造一个抽象类,即使是从一个子类。抽象类基本上是其他类的模板,它们本身没有构造函数。这是实现涉及继承的接口的另一种方式。

网上有很多关于多态的东西,而且都是愚蠢的。C++ 使您可以同时从多个类继承,因此抽象类和接口在那里是相同的。我认为抽象类存在的原因是因为某些语言,如 Java,只能从一个类继承/扩展。

抽象类实际上是一个抽象概念。他们是班级的家长,但仅限于我们的脑海中。它们是对没有正确答案的问题的答案。比如,“GTA 的前身是什么?” 你会说,“嗯,有 Race n'Chase”,但这甚至不是一个正确的答案,因为它们是同一个游戏,只是名称改变了。抽象类是“该类的父类是什么”的答案?就像你可以说“哦,字符串只是一个字符数组”和“一个字符数组只是几个迭代器”和“迭代器只是指针”。抽象类允许我们将这些愚蠢的答案形式化为继承。

于 2020-11-28T23:59:31.910 回答
0

就我而言,我在 COM 控制.idl文件中声明了一个函数,例如

[id(1)] HRESULT MyMethod([in]INT param);

但没有.h像这样在我的接口文件中声明

STDMETHOD(MyMethod)(INT param);

通过将以上行添加到我的界面 .h 文件中解决了问题

这可能会帮助一些人。

于 2015-12-28T07:49:52.267 回答