web-dev-qa-db-fra.com

Peut-on créer un constructeur de copie de classe virtuel en C++

Peut-on créer un constructeur de copie de classe virtuel en C++? Comment utiliser?

24
user1295465

Non, vous ne pouvez pas, les constructeurs ne peuvent pas être virtuels.

C++ 03 - 12.1 Constructeurs  

4) Un constructeur ne doit pas être virtual (10.3) ou static (9.4). [...]

Si vous avez besoin de quelque chose comme cela, vous pouvez rechercher l'idiome de constructeur virtuel ici .

22
Luchian Grigore

Non vous ne pouvez pas.

En outre, le concept n’a aucun sens. Les fonctions virtuelles sont des fonctions distribuées en fonction de la valeur d'un objet (le type dynamique de l'objet). Lorsqu'un constructeur est appelé, l'objet n'a pas encore de valeur (car il n'a pas encore été construit). Par conséquent, aucune répartition virtuelle ne peut éventuellement se produire.

Penses-y. Quelle sémantique aurait un tel constructeur?

4
Mankarse

Non. C++ étant un langage à typage statique, la création polymorphe d'un objet n'a pas de sens pour le compilateur C++. Le compilateur doit connaître le type de classe pour créer l'objet. En d'autres termes, le type d'objet à créer est une décision de compilation à partir du compilateur C++. Si nous rendons le constructeur virtuel, le compilateur signale une erreur. 

1
zsounder

Vous ne pouvez pas, car la mémoire est allouée avant l'appel du constructeur en fonction de la taille du nouveau type et non de l'opérande de copie. Et si cela fonctionnait, ce serait un cas spécial qui inverserait le polymorphisme pour un certain nombre de constructions de langage.

Mais cela ne signifie pas que cela ne peut pas être fait avec un peu de magie C++. :)

Dans certains cas, il est extrêmement utile, par exemple, de sérialiser des classes non-POD. Cet exemple crée un constructeur de copie virtuelle qui fonctionne en utilisant placement new. 

Avertissement: Ceci est un exemple qui peut aider certains utilisateurs avec des problèmes spécifiques. Ne faites pas cela dans le code à usage général. Il se bloquera si la mémoire allouée pour la nouvelle classe est plus petite que la classe dérivée. Le meilleur (et le seul) moyen sûr de l'utiliser est si vous gérez votre propre mémoire de classe et utilisez le placement.

class VirtualBase
{
public: 
    VirtualBase() {}
    virtual ~VirtualBase() {}

    VirtualBase(const VirtualBase& copy)
    {
        copy.VirtualPlacementCopyConstructor(this);
    }

    virtual void VirtualPlacementCopyConstructor(void*) const {}
};

class Derived :: public VirtualBase
{
public:
    ...

    Derived(const Derived& copy) : ... don't call baseclass and make an infinite loop
    {
    }

protected:
    void VirtualPlacementCopyConstructor(void* place) const
    {
        new (place) Derived(*this);
    }
};
1
George Davison

Jamais, cela ne sera pas possible en C++.

0
user1251300

Oui, vous pouvez créer un constructeur de copie virtuelle, mais vous ne pouvez pas créer de constructeur virtuel.

Raison:

Constructeur virtuel: - Non possible car c ++ est un langage de type statique et crée le constructeur en tant que virtuel. Le compilateur ne sera donc pas en mesure de décider du type d'objet et de laisser tout le processus pour l'exécution à cause du mot clé virtuel. Le compilateur doit connaître le type de classe pour créer l'objet. En d'autres termes, le type d'objet à créer est une décision de compilation à partir du compilateur C++. Si nous rendons le constructeur virtuel, le compilateur signale une erreur.

Constructeur Virtual Copy: - Oui Possible, envisagez l’application de presse-papiers. Un presse-papiers peut contenir différents types d'objets et copier des objets à partir d'objets existants, les coller sur le canevas de l'application. Encore une fois, le type d'objet à copier est une décision d'exécution. Le constructeur de copie virtuelle comble le vide ici. 

0
Priyanka Soni