这个继承有什么问题?

Fil*_*ącz 4 c++ templates

我只是不明白.试用VC++ 2008和G ++ 4.3.2

#include <map>


class A : public std::multimap<int, bool>
{
public:
    size_type erase(int k, bool v)
    {
        return erase(k); // <- this fails; had to change to __super::erase(k)
    }
};

int main()
{
    A a;
    a.erase(0, false);
    a.erase(0); // <- fails. can't find base class' function?!

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Gre*_*ill 26

当您在具有相同名称但与超类签名不同的类中声明函数时,名称解析规则指出编译器应在找到第一个匹配项后停止查找您尝试调用的函数.按名称查找功能后,适用的重载决策规则.

所以发生的事情是编译器erase(int, bool)在你调用时找到你的实现erase(0),然后决定参数不匹配.


jal*_*alf 17

1:从C++标准库容器派生时,您需要非常小心.它可以做到,但因为它们没有虚拟析构函数和其他类似的细节,所以通常是错误的方法.

2:重载规则在这里有点古怪.编译器首先查找派生类,如果它找到任何具有相同名称的重载,它将停止查找.如果在派生类中没有找到重载,它只在基类中查找.

一个简单的解决方案是将您需要的函数从基类引入派生类的命名空间:

class A : public std::multimap<int, bool>
{
public:
        using std::multimap<int, bool>::erase; // Any erase function found in the base class should be injected into the derived class namespace as well
        size_type erase(int k, bool v)
        {
                return erase(k);
        }
};
Run Code Online (Sandbox Code Playgroud)

或者,当然,您可以简单地在派生类中编写一个小辅助函数,重定向到基类函数


J F*_*cis 9

你在派生类具有相同的名称但不同的参数定义一个函数隐藏在基类的擦除成员函数.

http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9


Mar*_*cin 6

首先,您永远不应该从STL容器派生,因为没有STL容器定义虚拟析构函数.
其次,请参阅Greg关于继承的答案.


Enn*_*nno 5

想想你是否真的想继承std :: map.在我编写代码的所有时间里,这比STL存在的时间长,我从未见过从std :: container继承的实例是最好的解决方案.

具体来说,问问自己,你的等级是否IS多重映射或HAS多重映射.