2013-03-07 144 views
1

我有一个基类,它包含两个同名的函数,一个带有vector<int>作为参数,另一个带有int。这个想法是,子类将定义自己的方法来处理一个int,基类将能够处理任一选项。但目前它不能编译。抽象基类中的覆盖函数

class base { 
public: 
    virtual void toBeCalled(int i) const = 0; 

    virtual void toBeCalled(std::vector<int> iVec) const 
    { 
    std::cout << "base::toBeCalled(vec<int>)" << std::endl; 
    } 
}; 

class derived : public base { 
public: 
    virtual void toBeCalled(int i) const 
    { 
    std::cout << "derived::toBeCalled(int)" << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    derived d; 
    std::vector<int> iVec; 

    int i = 0; 

    d.toBeCalled (i); 
    d.toBeCalled (iVec); //<< Compile error: Cannot convert from std::vector<int> to int 

    return 0; 
} 

我可以得到它通过在main()base *d = new derived()使用基类对象工作,但我宁愿如果可能的话没有做到这一点,因为我想访问一些派生类的功能。

+0

在派生类中使用基名的使用。或者对冲突的功能使用其他名称。 – qPCR4vir 2013-03-07 11:15:22

+0

@WhozCraig我希望这是在复制/粘贴到SO:时出现错字:-)。 – qPCR4vir 2013-03-07 11:19:46

+0

你说得对,它确实存在,我现在已经纠正了这个问题。同样的错误仍然存​​在,虽然... – Chris 2013-03-07 11:22:22

回答

5

using base::toBeCalled;写入class derived

我很确定这是一个骗局,但我找不到一个,所以我不会详细介绍。但是当你在派生类中覆盖(或重载)一个函数时,你可以隐藏该函数的所有基类版本。

理由的行为在这里讨论:https://stackoverflow.com/a/12036004/13005

+0

+1伟大的链接。 = P(注意:将它添加到派生类的'public:'部分,顺便说一句)。 – WhozCraig 2013-03-07 11:19:49

3

您还没有造成class derived从基础的。

class derived: public base { 
+0

发生这种情况时,你说的东西要正常工作...... – 2013-03-07 11:16:05

+0

你是对的,它应该在那里,并在我的代码中,但我仍然得到同样的错误。我已经更新了这个问题。 – Chris 2013-03-07 11:20:53

0

你可以像这样称呼它,

base.toBeCalled(iVec); // here base is not base class name...it is reference to Parent Class 

其他方式 -

class derived : base { // inherit base class 
public: 
    virtual void toBeCalled(int i) const 
    { 
    std::cout << "derived::toBeCalled(int)" << std::endl; 
    } 
}; 
2

我会假设你忘了指定的基类复制代码时这里。这是不是,:

class derived { 
public: // and so on 

您有:

class derived : public base { 
public: // and so on 

当你定义一个类的方法,这些方法与隐藏在基类中相同名称的任何方法。在这种情况下,当您覆盖方法toBeCalled()时,您在说类derived将只具有您指定的那些签名;在基类中的任何其它签名将被隐藏:

class derived : public base { 
public: 
    virtual void toBeCalled(int i) const 
    { 
    std::cout << "derived::toBeCalled(int)" << std::endl; 
    } 
    // void base::toBeCalled(std::vector<int> iVec) const is hidden and 
    // cannot be accessed through this class 
}; 

既然你不想覆盖的方法的第二个版本在你的派生类,你最好的办法就是明确地告诉你想要的编译器导入(而不是隐藏)方法的所有基类版本到您的派生类中。这是通过using子句完成的:

class derived : public base { 
public: 
    using base::toBeCalled; // Any version of method toBeCalled() not overriden here 
          // will now be taken from the base class 
    virtual void toBeCalled(int i) const 
    { 
    std::cout << "derived::toBeCalled(int)" << std::endl; 
    } 
    // void base::toBeCalled(std::vector<int> iVec) const is taken 
    // from the base class now 
}; 
+0

+1,但值得指出的是,名称隐藏并不局限于成员函数:派生类可以有一个名为'toBeCalled'的私有字符,这仍然会隐藏所有的基类“toBeCalled'。 – juanchopanza 2013-03-07 11:43:37

+1

@juanchopanza绝对正确,但我不想过分复杂的答案。这种机制不是方法隐藏,而是名称隐藏。 – Gorpik 2013-03-07 14:38:43