2012-08-06 421 views
9

如何在C++中處理「無法實例化抽象類」錯誤? 我已經看過一些類似的錯誤在這裏,沒有一個看起來是完全一樣的或我有問題。但是,我再次承認,有幾個要過去。以下是編譯錯誤:如何在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++程序,但該頁面調用抽象類的「接口」:

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.

壞消息是我已經在課堂上公開了所有的方法:

class AmbientOccluder: public Light { 
    public: 

     AmbientOccluder(void); 
+0

@dasblinkenlight IIRC,這是可選的。然而,後者默認構造該對象。但不是一個錯誤。另請參閱:http://ideone.com/LWbg6 – Drise 2012-08-06 18:41:22

+1

@dasblinkenlight嗯,不,不需要括號。 – 2012-08-06 18:41:46

+5

@dasblinkenlight是否有太多的Java和C#,是不是? – 2012-08-06 18:42:03

回答

24

錯誤表示該類有一些方法未實現。你不能實例化這樣的類,所以除了實現類的方法全部以外,沒有任何可以做的事情。

在另一方面,一個共同的模式是實例化一個具體的類,並將其分配到一個abstrate基類的指針:

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

Abstract* pAbs = new Derived; // OK 

只是順便說一句,爲了避免與上述行存儲器管理問題,你可以如`的std ::的unique_ptr考慮使用smart pointer,:

std::unique_ptr<Abstract> pAbs(new Derived); 
+0

好吧,我試着評論AmbientOccluder中的所有方法,並進行了構建以確保所有方法都得到了解決。他們是。所以在這個層面上,並不是因爲某些方法沒有屍體。我會在父類上試一試。 – xarzu 2012-08-06 18:49:05

+0

@xarzu如果'AmbientOcluder'有一個基類,那麼也可以在那裏查找未實現的方法。否則,你的編譯器錯誤是最具誤導性的! – juanchopanza 2012-08-06 18:52:32

+0

@juanchopanza'AmbientOcluder'繼承自'Light'。 – 2012-08-06 18:55:10

6

抽象類不能被定義來instanctiated。爲了使用這個類,你必須創建一個實現該類的所有虛函數的具體子類。在這種情況下,您很可能尚未實現Light中聲明的所有虛函數。這意味着AmbientOccluder默認爲抽象類。爲了進一步幫助你,你應該包括Light課程的細節。

3

爲該類所具有的任何純虛函數提供實現。

19

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' 
1

爲什麼我們不能創建抽象類的對象? 當我們在Abstract類中創建一個純虛函數時,我們在VTABLE(在上一個主題中進行了研究)中爲函數預留了一個插槽,但沒有在該插槽中放置任何地址。因此VTABLE將不完整。 由於抽象類的VTABLE是不完整的,因此編譯器不會爲這樣的類創建對象,並且只要您嘗試這樣做就會顯示錯誤消息。

純虛擬的定義

純虛函數可以給出在抽象類小的定義,你希望所有的派生類有。仍然無法創建Abstract類的對象。 此外,PureVirtual函數必須在類定義之外定義。如果你要在類定義中定義它,編譯器會給出錯誤。內聯純虛擬定義是非法的。

0

在我的情況我聲明在COM控制的功能.idl文件等

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

但不是在我的接口.h文件等通過添加上述行到我的接口解決了這個

STDMETHOD(MyMethod)(INT param); 

問題聲明.h文件

這可能對某個人有幫助。