2017-01-03 84 views
1

抽象類具有內部虛函數。 抽象類是否可以稍後實現內部虛擬類?如何在C++中實現內部抽象成員類?

我嘗試以下:

#include <bits/stdc++.h> 
using namespace std; 

class C1 { 
    public: 
     class Child { 
      int tmp; 
      virtual int getint() = 0; 
     }; 
    virtual Child getChild() = 0; 
}; 

class C2: public C1 { 
    public: 
     class Child { 
      int getint() 
      { 
       return 10; 
      } 
     } c; 
    Child getChild() 
    { 
     return c; 
    } 
}; 

int main() { return 0; } 

兒童是一個抽象類,這將在派生類中推翻。我希望執行可以用來定義一個函數。

但是,我得到了一個錯誤:

invalid abstract return type for member function 'virtual C1::Child C1::getChild()'

我不能實施內部抽象類中派生類,就像實現虛擬函數?

+0

這與內部類沒有任何關係。你可以極大地簡化你的例子。這裏有一個[mcve]:'struct foo {virtual stuff()= 0; }; foo make_foo();'。 – juanchopanza

+0

您不能將抽象對象作爲值返回。如果你這樣做,那麼客戶如何使用它,因爲缺少'純虛函數'的實現?但是你可以返回指向這個對象的指針。另外:在你的例子中,'Child'不是抽象的。將其編輯爲某人可能不瞭解您的問題。 –

+0

@MichałWalenciak客戶端調用該抽象類中定義的虛函數。 –

回答

2

在本代碼中,class C1::Childclass C2::Child沒有繼承關係。因此他們完全沒有關係。即使你將它們與繼承關聯起來,那麼getChild()也不能返回Child(值)。它可以返回Child&(參考)或Child*(指針)以形成有效的virtual方法,其中協方差。參考:C++ virtual function return type

這樣的錯誤很容易通過在C++ 11中使用override說明符來捕獲。

不知道你正在努力實現什麼確切的情況下,可能的代碼應該是這樣的:

class C1 { 
    // ... same 
    virtual Child& getChild() = 0; 
    //  ^^^^^^ reference 
}; 

class C2 : public C1 { 
//   ^^^^^^ did you miss this? 
public: 
    class Child : public C1::Child { 
    //     ^^^^^^^^^ inheritance 
    int getint() override { return 10; } 
    } c; 
    Child& getChild() override { return c; } 
}; 

而且你下面的語句顯得撲朔迷離:

"Child is a abstract class, which will be implemented later,"

像方法,這些類不具有這樣的運行時間關係。
類的背景下「後實施」的最好含義 - 實現它的封閉類的身體之外,如:

class Outer { public: class Inner; }; 
// ... 
class Outer::Inner { ... }; 
+0

那麼虛擬函數和抽象類和對待不同?我可以調用一個虛函數,但是我不能使用抽象類? –

+1

@ZehuiLin,我不清楚你的確切Qn。然而,抽象類是在其主體內至少有一個純虛擬方法的類。使用基類引用或指針調用'virtual'方法。如果基類是抽象的,那麼你不能擁有它的對象。如果你不清楚,我會建議舉一些例子。有關抽象類的更多詳細信息,請參閱以下內容:[C++中的抽象類與接口](http://stackoverflow.com/q/12854778/514235) – iammilind

0

從您的文章,你似乎是令人困惑的事情。我建議你重新閱讀抽象類,並親自嘗試一些簡單的例子。

Child is a abstract class, which will be implemented later, And I hope the implemented Child can be used to define a function.

純虛方法(virtual int getint() = 0;在你的例子)不意味着是「後」來實現。它意味着通過派生類中的重寫方法實現。

E.g.如果你有

class Child { 
    virtual int getint() = 0; 
}; 

你不能做

class Child { 
    virtual int getint() { return 10; } 
}; 

也不

int Child::getint() { return 10; } 

在以後的時間。

你可以做的是:

class Derived : public Child 
{ 
    int getint() override { return 10; } 
}; 
1

理論上,Abstract Classes用於創建Interfaces。使用Interfaces,客戶端需要所需的功能。通過定義/實現Interfaces,服務器可以實現客戶端的功能。 Interface/Abstract Class只是客戶端和服務器之間需求/協議的藍圖。實現Interface/Abstract Class或滿足功能要求的類可以實例化。所以可以有很多實現相同的Interface/Abstract Class。現在爲了在不同的時間點訪問所有這些不同時間的相同的Interface/Abstract Class實現,我們需要一個通用的方法。這種廣義的方式是通過pointer(*) or reference(&)到底層的Interface\Abstract Class

在您的代碼C1::Child是一個Abstract Class or Interface

因此,C1::getChild()可以返回執行Interface/Abstract C1::Child。但根據上述理論解釋,它不能返回Interface/Abstract C1::Child本身的實例。因此錯誤。 申報C1::getChild()正確的方法是:

  • virtual C1::Child* getChild() = 0;
  • virtual C1::Child& getChild() = 0;

此外,C1::Child可以簡單地看作是一個classnamespace C1,因爲class也是一種namespace一些限制。