在C ++中重写方法

时间:2017-06-20 01:08:45

标签: c++ override

我试图在继承的类NumericInput中覆盖函数add()。但是当我在NumericInput对象上调用add()时,会调用基类中的add()函数。这是为什么?

#include <iostream>
#include <string>

class TextInput
{
public:
    std::string cur;
    void add(char c) 
   {
        cur += c;
        std::cout<<"input is: "<<c<<'\n';
   }

   std::string getValue() {return cur;}
};

class NumericInput : public TextInput 
{
   public:
   void add(char c) 
   {
    if(c>=48 && c <= 57)
    {
        std::cout<<"input is a digit: "<< c <<'\n';
        cur += c;
    }
    else
    {
        std::cout<<"input is not digit"<<'\n';}
    }
};

int main()
{
    TextInput* input = new NumericInput();
    input->add('1');
    input->add('a');
    input->add('0');
    std::cout << input->getValue();
}

2 个答案:

答案 0 :(得分:1)

如评论中所述,将其设为virtual。使用override标记覆盖函数也是一种很好的做法。这样,当没有要覆盖的函数时(通常是因为名称中的拼写错误),您将收到编译器错误。

任何具有虚函数的类都应该有一个虚析构函数,以便可以通过指针删除它。别忘了删除指针!

#include <iostream>
#include <string>

class TextInput
{
public:
    std::string cur;

    virtual ~TextInput() = default;

    virtual void add(char c)
    {
        cur += c;
        std::cout<<"input is: "<<c<<'\n';
    }

    std::string getValue() {return cur;}
};

class NumericInput : public TextInput 
{
public:
    virtual void add(char c) override
    {
        if(c>=48 && c <= 57)
        {
            std::cout<<"input is a digit: "<< c <<'\n';
            cur += c;
        }
        else
        {std::cout<<"input is not digit"<<'\n';}
    }
};

#ifndef RunTests
int main()
{
    TextInput* input = new NumericInput();
    input->add('1');
    input->add('a');
    input->add('0');
    std::cout << input->getValue() << '\n';
    delete input;
}
#endif

这也是应用非虚拟界面成语的好地方。基类有一个成员函数add,它不是虚拟的,并负责将字符添加到字符串cur。如果do_add报告应添加该字符,则会这样做。函数do_add是虚拟的,最重要的是私有。这确保了封装并使类可移植。请参阅Scott Meyers的 Effective C ++ 中的第35项“考虑虚拟函数的替代方法”。

另外,使用std::unique_ptr来管理班级的记忆。

#include <iostream>
#include <string>
#include <memory>

class TextInput
{
    std::string cur;

    virtual bool do_add(char c)
    {
        std::cout<<"input is: "<<c<<'\n';
        return true;
    }

public:
    virtual ~TextInput() = default;

    void add(char c)
    {
        if ( do_add(c) )
            cur += c;
    }

    std::string getValue()
    {
        return cur;
    }
};

class NumericInput : public TextInput 
{
    virtual bool do_add(char c) override
    {
        if ( c>=48 && c <= 57 )
        {
            std::cout<<"input is a digit: "<< c <<'\n';
            return true;
        }

        std::cout<<"input is not digit"<<'\n';
        return false;
    }
};

#ifndef RunTests
int main()
{
    auto input = std::unique_ptr<TextInput>{new NumericInput()};
    input->add('1');
    input->add('a');
    input->add('0');
    std::cout << input->getValue() << '\n';
}
#endif

答案 1 :(得分:0)

我建议使用:

bool my_isdigit(char ch)
{
    return std::isdigit(static_cast<unsigned char>(ch));
}

为了验证您的字符是否为数字