36 votes

Une classe peut-elle avoir des membres virtuels ?

class Base{  
    public:  
        void counter();   
    ....   
}

class Dervied: public Base{  
    public:  
        ....  
}

void main()  
{  
     Base *ptr=new Derived;  
     ptr->counter();  
}

Pour identifier que le pointeur de la classe de base pointe vers une classe dérivée et utilise une fonction membre dérivée, nous utilisons le terme "virtuel".

De même, peut-on rendre les membres de données dérivés "virtuels" (le membre de données est public) ?

2voto

Igor Zevaka Points 32586

Non, car cela briserait l'encapsulation d'une myriade de façons inattendues. Tout ce que vous voulez réaliser peut être fait avec des attributs protégés et/ou des fonctions virtuelles.

En outre, les fonctions virtuelles sont une méthode de envoi (c'est-à-dire la sélection de la fonction qui sera appelée), plutôt que de sélectionner un emplacement de mémoire correspondant à l'attribut du membre.

1voto

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

1voto

Keith Points 29

J'ai une classe de base qui utilise un tableau d'objets. À partir de cette classe, j'ai dérivé une nouvelle classe qui utilise un tableau d'un autre type d'objet. Les deux variables portent exactement le même nom. Des fonctions membres virtuelles ont été ajoutées aux deux classes pour traiter les tableaux. Ces fonctions membres n'ont aucun mal à trouver la bonne variable. Les fonctions membres et les variables qu'elles utilisent sont dans une portée commune.

Les fonctions membres virtuelles sont pratiquement identiques dans les deux classes. Seul le type de tableau a changé.

Les modèles C++ auraient permis d'obtenir le même résultat.

0voto

Mauro Points 1

Peut-être pouvez-vous voir le problème d'une manière équivalente :

class VirtualDataMember{  
    public:  
    ...
}

class DerviedDataMember: public VirtualDataMember{  
    public:  
    ... 
}

class Base{  
    public:  
        VirtualDataMember* dataMember;
        void counter();     
        ...  
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X