2013-05-09 281 views
1

在我的節目,我有這樣的類層次結構:在編譯過程中抽象類:無效的抽象的返回類型爲成員函數「虛擬...」

#include <iostream> 
#include <cmath> 
#include <sstream> 
using namespace std; 

class aa; 
class bb; 

class root 
{ 
public: 
    virtual ~root() {} 
    virtual root add(const aa& a) const=0; 
    virtual root add(const bb& a) const=0; 
}; 

class aa: public root 
{ 
public: 
    aa() { } 
    aa(const aa& a) { } 

    virtual root add(const aa& a) const 
    { return root(new aa()); } 
    virtual root add(const bb& a) const 
    { return root(new bb()); } 
}; 

class bb: public root 
{ 
public: 
    bb() { } 
    bb(const bb& b) {} 

    virtual root add(const aa& a) const 
    { return root(new bb()); } 
    virtual root add(const bb& a) const 
    { return root(new bb()); } 
}; 

int main(int argc, char **argv) 
{ 
} 

但是我仍然得到錯誤。我不能改變我的類層次結構,但可以在這裏創建我想要的東西嗎?

EDITED類:

#include <iostream> 
#include <cmath> 
#include <sstream> 
using namespace std; 

class root 
{ 
public: 
    virtual ~root() {} 
    virtual root add(const root& a) const=0; 
    virtual root add(const root& b) const=0; 
}; 

class aa: public root 
{ 
public: 
    aa() { } 
    aa(const aa& a) { } 

    virtual root add(const root& a) const 
    { return root(new aa()); } 
    virtual root add(const root& b) const 
    { return root(new bb()); } 
}; 

class bb: public root 
{ 
public: 
    bb() { } 
    bb(const bb& b) {} 

    virtual root add(const root& a) const 
    { return root(new bb()); } 
    virtual root add(const root& b) const 
    { return root(new bb()); } 
}; 

int main(int argc, char **argv) 
{ 
} 

誤差的編輯類:

/home/brian/Desktop/Temp/Untitled2.cpp|11|error: ‘virtual root root::add(const root&) const’ cannot be overloaded| 
/home/brian/Desktop/Temp/Untitled2.cpp|10|error: with ‘virtual root root::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|10|error: invalid abstract return type for member function ‘virtual root root::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: because the following virtual functions are pure within ‘root’:| 
/home/brian/Desktop/Temp/Untitled2.cpp|10|note:  virtual root root::add(const root&) const| 
/home/brian/Desktop/Temp/Untitled2.cpp|11|error: invalid abstract return type for member function ‘virtual root root::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|20|error: invalid abstract return type for member function ‘virtual root aa::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|22|error: invalid abstract return type for member function ‘virtual root aa::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|22|error: ‘virtual root aa::add(const root&) const’ cannot be overloaded| 
/home/brian/Desktop/Temp/Untitled2.cpp|20|error: with ‘virtual root aa::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp||In member function ‘virtual root aa::add(const root&) const’:| 
/home/brian/Desktop/Temp/Untitled2.cpp|20|error: invalid abstract return type for member function ‘virtual root aa::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|21|error: cannot allocate an object of abstract type ‘root’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp||In member function ‘virtual root aa::add(const root&) const’:| 
/home/brian/Desktop/Temp/Untitled2.cpp|22|error: invalid abstract return type for member function ‘virtual root aa::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|23|error: cannot allocate an object of abstract type ‘root’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|23|error: expected primary-expression before ‘(’ token| 
/home/brian/Desktop/Temp/Untitled2.cpp|23|error: expected type-specifier before ‘bb’| 
/home/brian/Desktop/Temp/Untitled2.cpp|23|error: expected ‘)’ before ‘bb’| 
/home/brian/Desktop/Temp/Untitled2.cpp|32|error: invalid abstract return type for member function ‘virtual root bb::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|34|error: invalid abstract return type for member function ‘virtual root bb::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|34|error: ‘virtual root bb::add(const root&) const’ cannot be overloaded| 
/home/brian/Desktop/Temp/Untitled2.cpp|32|error: with ‘virtual root bb::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp||In member function ‘virtual root bb::add(const root&) const’:| 
/home/brian/Desktop/Temp/Untitled2.cpp|32|error: invalid abstract return type for member function ‘virtual root bb::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|33|error: cannot allocate an object of abstract type ‘root’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp||In member function ‘virtual root bb::add(const root&) const’:| 
/home/brian/Desktop/Temp/Untitled2.cpp|34|error: invalid abstract return type for member function ‘virtual root bb::add(const root&) const’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
/home/brian/Desktop/Temp/Untitled2.cpp|35|error: cannot allocate an object of abstract type ‘root’| 
/home/brian/Desktop/Temp/Untitled2.cpp|6|note: since type ‘root’ has pure virtual functions| 
||=== Build finished: 38 errors, 0 warnings ===| 
+1

你的設計有點搞砸了。你的基類需要知道派生類型,這是不好的。你應該考慮使用一個成員函數'虛擬根加法(const root&a)const = 0;' – juanchopanza 2013-05-09 08:34:37

+0

@juanchopanza:Ok改變了它,但仍然有錯誤。看看我編輯的問題。 – 2013-05-09 08:37:07

+0

這個問題在KerrekBS的答案中熟練處理。另一種方法是返回一個引用,但是你必須確保總是有可以引用的東西。 – juanchopanza 2013-05-09 08:43:12

回答

7

您不能返回root的值,因爲root是抽象的,因此有可能不會存在類型的值root

您可能要返回一個指針:

#include <memory> 

std::unique_ptr<root> do_you_feel_lucky(aa const & x, bb const & y) 
{ 
    if (rand() % 2 == 0) 
     return { new aa(x) }; 
    else 
     return { new bb(y) }; 
} 

你有什麼感覺很像一個「克隆」或「虛擬拷貝」功能,雖然:

struct Base 
{ 
    virtual std::unique_ptr<Base> clone() const = 0; 
}; 

struct Derived : Base 
{ 
    virtual std::unique_ptr<Base> clone() const 
    { 
     return { new Derived(*this); } 
    } 
}; 

既然你問起引用,下面是你可以做的另一件事情,儘管看起來有點沒有意義:選擇一個對多個派生對象中的一個的引用,並返回一個基本引用。

root & pick_one_from_two(aa & x, bb & y) 
{ 
    return rand() % 2 == 0 ? x : y; 
} 
+0

+1。但是它是因爲它不能構造抽象類的對象嗎?我們可以通過參考返回嗎? – 2013-05-09 08:45:18

+0

@Koushik:引用* what *?是的,在我的示例中,您可能會試圖將'x'或'y'作爲'root const&'返回,但您會遇到生存期問題。使用非常量引用可能會更好,但通常不會非常有用(畢竟,您希望*創建新對象)。我會做一些編輯。 – 2013-05-09 09:09:59

+0

引用root? – 2013-05-09 09:11:21