至於說在註釋,使其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
使其成爲'虛擬'。 – songyuanyao
調用指向基類的指針的方法將始終調用基類成員函數,除非該函數是虛擬的。 –