2013-05-09 287 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