Une classe ne peut pas avoir de membre virtuel, voir par exemple ceci répondre . Cependant, il est possible d'obtenir quelque chose de similaire en utilisant des pointeurs, l'héritage et le polymorphisme d'exécution.
Dans l'extrait suivant, je définis le prototype d'un objet géométrique shape
, qui a une area
méthode. La méthode picture
possède un membre shape* s;
et les méthodes de cette shape
pointé par s
sont utilisés par picture::show()
. Dans cette configuration, il n'est pas souhaitable d'avoir une instance de picture
avant la mise en œuvre effective d'un shape
a été donnée, nous forçons donc picture
être abstraite en ajoutant une fonction virtuelle factice picture::make_real()
.
// prototypes
class shape
{
public:
virtual double area() = 0; // to be defined later
};
class picture
{
protected:
shape* s;
virtual void make_real() = 0; // force picture to be abstract
public:
picture(shape* ptr):
s{ptr}
{}
void show()
{
std::cout << s->area() << '\n';
}
};
Ensuite, nous mettons en œuvre un shape
appelé square
et un picture
type square_picture
qui a (littéralement) un square
shape
.
// actual implementation
class square : public shape
{
double len;
public:
square(double l):
len{l}
{}
double area() override
{
return len*len;
}
};
class square_picture : public picture
{
void make_real() override {} // square_picture is not abstract
public:
square_picture(double l):
picture{new square{l}}
{}
~square_picture()
{
delete s;
}
};
La classe square_picture
peut être testé à l'aide de l'extrait suivant
int main()
{
square_picture A{2.0};
A.show();
//picture B{nullptr}; // error: picture is abstract
return 0;
}
qui produit :
4