Comme dit dans le commentaire, faire virtual
. Il est également recommandé de marquer la fonction principale avec override
. De cette façon, vous obtiendrez une erreur de compilation quand il n'y a pas de fonction à remplacer (généralement à cause d'une faute de frappe dans le nom).
De plus, toute classe avec des fonctions virtuelles doit avoir un destructeur virtuel afin de pouvoir être supprimé via un pointeur. Ne pas oublier de supprimer le pointeur aussi bien!
#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
Ceci est également un bon endroit pour appliquer le langage d'interface non-virtuelle . La classe de base a une fonction membre add
qui n'est pas virtuelle et qui prend en charge l'ajout du caractère à la chaîne cur
. Il le fait si do_add
signale que le caractère doit être ajouté. La fonction do_add
est virtuelle et, surtout, privée. Cela assure l'encapsulation et rend la classe portable. Reportez-vous à l'article 35 "Prise en compte des alternatives aux fonctions virtuelles" dans En vigueur C++ par Scott Meyers.
De même, utilisez un std::unique_ptr
pour gérer la mémoire de votre classe.
#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
Faites-le 'virtuel'. – songyuanyao
L'appel d'une méthode d'un pointeur à la classe de base appelle toujours la fonction de membre de la classe de base sauf si cette fonction est virtuelle. –