2014-02-19 86 views
0

我創建了在C++中使用其他接口的接口(抽象類),並試圖實現它們,但編譯時發生錯誤。C++實現擴展子接口而不覆蓋已覆蓋的方法的子類

下面是錯誤:

main.cpp: In function 'int main()': 
main.cpp:36:38: error: cannot allocate an object of abstract type 'Subclass' 
    Subclass * subObj = new Subclass(); 
            ^
Subclass.h:13:7: note: because the following virtual functions are pure within 'Subclass': 
class Subclass : SubInterface { 
    ^
SuperInterface.h:13:18: note: virtual void SuperInterface::doSomething() 
    virtual void doSomething()=0; 

這裏是我的消息來源:

#include <iostream> 

class SuperInterface { 
public: 
    virtual void doSomething() = 0; 
protected: 
    int someValue; 
}; 

class SubInterface : public SuperInterface { 
public: 
    virtual void doSomethingElseThatHasNothingToDoWithTheOtherMethod() = 0; 
protected: 
    int anotherValue; 
}; 

class Superclass : public SuperInterface { 
public: 
    Superclass() {} 
    virtual ~Superclass() {} 
    void doSomething() {std::cout << "hello stackoverflow!";} 
}; 

class Subclass : public SubInterface { 
public: 
    Subclass() {} 
    virtual ~Subclass() {} 
    void doSomethingElseThatHasNothingToDoWithTheOtherMethod() {std::cout << "goodbye stackoverflow!";} 

}; 

int main(void) 
{ 
    Superclass * superObj = new Superclass(); 
    Subclass * subObj = new Subclass(); 
} 

這是我想要的東西: 我想我的實現要知道等有與已經被覆蓋的方法相同的行爲(例如,subObj->doSomething()方法不需要再次實施)。任何人都可以告訴我,如果甚至有可能發生,我該怎麼做?謝謝。

+0

只是用我的眼睛解析你的代碼。像Subclass這樣的Seens聲明doSomethingElse是純虛擬的。這是一個錯字,對嗎? –

+1

公開派生,在Subclass :: doSomethingElse聲明中除去= 0並在Subclass中實現doSomething。那麼你不必公開派生,但它可能是你想要的。默認情況下類私下繼承。我使用純粹的接口結構。 – codah

+0

這是一個錯字,我的錯誤,我改名爲另一種方法,以明確兩種方法有不同的行爲。 –

回答

2

不,你不能通過簡單的繼承來做你想做的事。 Subclass不會繼承或提供doSomething()的實現,因此您無法根據需要調用subObj->doSomething()。您必須遵守subInterface的接口合同。

你可以繼承SuperclassSubinterfaceSubclass,只是實施doSomething()作爲一種代理,Superclass::doSomething()的。你仍然需要一個實現,但你不必'重新實現'它。

2

由於您嘗試創建抽象類的對象,因此出現錯誤。 由於此行void doSomethingElse()=0;,您的Subclass是一個抽象類。 如果一個類有一個純虛函數,它將是一個抽象類。你不能創建一個抽象類的對象,你只能有一個引用或一個指針。

爲了擺脫錯誤的doSomethingElseSubclass聲明應該是

void doSomethingElse(); 

而不是void doSomethingElse()=0;

此外,我不明白爲什麼你需要兩個接口。你可以從SuperInterface獲得Subclass,因爲它基本上是一樣的SubInterface

+0

doSomethingElse()重命名以清楚說明doSomething()和doSomethingElse()完全沒有共同之處I也可能有完全不同的行爲和返回類型。該= 0是現在糾正的錯字! –

0

你的類的子類「應覆蓋2種純虛方法,所以:

class Subclass : SubInterface { 
public: 
    Subclass(); 
    virtual ~Subclass(); 
    void doSomethingElse() override; 
    void doSomething() override; 
}; 

通過不這樣做或聲明

void doSomethingElse()= 0;

class子類也變得抽象了,不能被實例化。你可以havea看看:http://www.parashift.com/c++-faq-lite/pure-virtual-fns.html

這是我想要的東西:我想我的實現要知道等有 相同的行爲已經重寫的方法(如 subObj-> DoSomething的()方法的工作,而不需要再次執行它 )。任何人都可以告訴我,我應該怎麼做,如果 甚至可能!! !! ??謝謝。

- >也許申報方法不虛純虛

+1

可以爲方法聲明添加「覆蓋」。 – codah

+0

是的,的確,修改(註釋+1) – AdR

+0

我知道爲什麼子類變得抽象了,我的問題是:有沒有辦法,解決方法是不必再次覆蓋已覆蓋的方法。 –

0

說實話,我並不完全確保設計想要什麼來表達,但這裏至少有兩個技術錯誤:

1。)在所有情況下,您都使用私有繼承,所以根本沒有實際處理「接口」。公共繼承取得這樣的:

class SubInterface : public SuperInterface 

2)使用=0你顯然是想實現一個功能。

這將修復編譯器錯誤,但設計仍然有問題。考慮到你在問題結束時給出的動機,我推薦組合而不是(公共)繼承。在C++中,共享功能最好用組合來表達。簡而言之,將常用功能封裝在一個單獨的類中,併爲其他類提供一個對象。

class CommonFunctionality 
{ 
//... 
public: 
    void doSomething(); 
    void doSomethingElse(); 
}; 

class SuperClass 
{ 
//... 
private: 
    CommonFunctionality m_functionality; 
}; 

class SubClass : public SuperClass 
{ 
//... 
private: 
    CommonFunctionality m_functionality; 
}; 

事實上,也許你甚至都不需要創建一個類CommonFunctionality。也許簡單的獨立功能會做。具有Java背景的程序員(和你的代碼看起來有點像它)往往把太多東西放入類中,而不是C++中必需的東西。

+0

這是一個錯字,我的錯誤,我改名爲另一種方法,以清楚地表明兩種方法都有不同的行爲。順便在繼承聲明中加入「public」並不會改變我的代碼錯誤 –

0

有2個問題,其中明確由編譯器說:

問題1

SubclassSubInterface::doSomethingElse()()被聲明爲純虛,無論你想在源文件中定義它(我非常確定,這是一種複製粘貼類型的錯誤)。


class Subclass : SubInterface 
{ 
public: 
    Subclass(); 
    virtual ~Subclass(); 
    void doSomethingElse() = 0; // still pure? 
}; 

解決方案是顯而易見的:


class Subclass : SubInterface 
{ 
public: 
    Subclass(); 
    virtual ~Subclass(); 
    virtual void doSomethingElse() override { }  
}; 

(這裏使用C++ 11 override說明符,所以編譯器將檢查重寫的正確性;它不是強制性的)

問題2

doSomething()甚至沒有嘗試被覆蓋,在SuperInterface,也不在Subclass,所以它保持純虛擬。雖然doSomething()Superclass中被覆蓋,但Subclass不知道存在Superclass

enter image description here

解決方案:覆蓋doSomething()無論是在SuperInterface,或Subclass,或以任何的Subclass兒童(沒有他們還)。例如,它將覆蓋Subclass


class Subclass : SubInterface 
{ 
public: 
    Subclass(); 
    virtual ~Subclass(); 
    virtual void doSomething() override { }  
    virtual void doSomethingElse() override 
    { 
    } 

}; 

其他問題:

  • 你沒有知名度符繼承,即privat伊利。使用public繼承,直到你真正需要別的東西:

    class Derved : public Base {}; 
    
  • 你的源文件具有.c擴展,但含C++代碼。如果你沒有通過命令行參數明確地聲明編程語言,這可能會混淆一些編譯器。按照慣例,大多數程序員使用.cpp擴展,大多數編譯器將這些文件視爲C++源文件。

+0

的更正。事實是,我無意中刪除了部分代碼。我也做了一些修改,使整個事情,我希望更清晰! –

+0

@PaikuHan好了,第一個問題解決了,其他人仍然在那裏。 – Drop

+0

@PaikuHan順便說一句,不建議你編輯你的第一個修復後的問題。這會給任何稍後閱讀本主題的人增加混淆。 – Drop