appelez le constructeur de copie de l'opérateur d'assignation de fonction
J'ai une classe avec un point à allouée dynamiquement tableau, j'ai donc créé constructeur de copie et l'opérateur d'affectation de la fonction. Depuis le constructeur de copie et l'opérateur d'affectation de la fonction de faire le même travail, j'appelle constructeur de copie de l'opérateur d'affectation de la fonction, mais obtenir "error C2082: redefinition of formal parameter"
. Je suis à l'aide de Visual Studio 2012.
//default constructor
FeatureValue::FeatureValue()
{
m_value = NULL;
}
//copy constructor
FeatureValue::FeatureValue(const FeatureValue& other)
{
m_size = other.m_size;
delete[] m_value;
m_value = new uint8_t[m_size];
for (int i = 0; i < m_size; i++)
{
m_value[i] = other.m_value[i];
}
}
//assignment operator function
FeatureValue& FeatureValue::operator=(const FeatureValue& other)
{
FeatureValue(other); //error C2082: redefinition of formal parameter
return *this;
}
OriginalL'auteur stackunderflow | 2013-07-05
Vous devez vous connecter pour publier un commentaire.
La ligne incriminée n'est pas ce que vous pensez qu'elle est. Il fait déclare une variable
other
de typeFeatureValue
. C'est parce que les constructeurs de ne pas avoir de noms et ne peut pas être appelée directement.Vous pouvez appeler l'opérateur d'assignation de copie à partir du constructeur, tant que l'opérateur n'est pas déclarée virtuelle.
Cela travaille juste dandy ou vous pouvez utiliser le typique lignes directrices pour la copie & échanger de l'idiome suggéré dans Vaughn de Caton répondre
m_value[i] = other.m_value[i]
au lieu d'utiliser les valeurs intermédiaires, par exemplevalue[i] = other.m_value[i]
?OriginalL'auteur Captain Obvlious
Vous ne pouvez pas appeler un constructeur comme vous le feriez de toute autre méthode. Ce que vous faites est en fait de déclarer une variable appelée
other
de typeFeatureValue
.Prendre un coup d'oeil à la copie-et-swap idiome pour une bonne manière d'éviter les chevauchements entre l'opérateur d'affectation et le constructeur de copie: Qu'est-ce que la copie-et-swap idiome?
Mieux encore, utiliser une
std::vector
au lieu denew
etdelete
. Ensuite, vous n'avez pas besoin d'écrire votre propre copie, le constructeur ou l'opérateur d'affectation.Son étrange la façon dont vous deux, vous avez répondu la même chose au même moment.
ce que vous pouvez trouver encore plus étrange c'est que j'ai savoir sur Vaughn pour les plus de 25 ans. Il ne savait pas à propos de moi 😉
Ok. Est-il possible d'appeler constructeur de copie de l'opérateur d'affectation de la fonction?
Pas-vous pourriez mettre le code dans une troisième fonction que le constructeur et l'opérateur d'affectation appel.
OriginalL'auteur Vaughn Cato
Réponse courte - ne pas le faire.
Détails:
Notes:
m_value
a une valeur indéterminée lorsque le constructeur de copie commence à courir: vous pouvez attribuer à elle, mais à lire c'est un comportement indéterminé, et àdelete[]
considérablement le pire (si quelque chose peut être pire que UD! ;-)). Donc, il suffit de laisser quedelete[]
ligne.Prochaine, si
operator=
essaie de tirer parti de la fonctionnalité de l'constructeur de copie, il a d'abord communiqué toutes les données existantesm_value
pointe ou il sera coulé. La plupart des gens essayer de faire comme suit (qui est cassé) - je pense que c'est ce que vous essayiez de:Le problème avec cela est que si la création de FeatureValue échoue (par exemple, parce que
new
ne pouvez pas obtenir le mémoire qu'il veut), puis leFeatureValue
objet est mis avec un état non valide (par exemple,m_value
peut être orienté dans l'espace). Plus tard, lorsque le destructeur court et fait undelete[] m_value
, vous avez un comportement indéterminé (votre programme sera probablement planter).Vous devriez vraiment cette approche de manière plus systématique... soit l'écrire, étape par étape, ou peut-être la mise en œuvre d'une garantie de non-lancer
swap()
méthode (facile à faire... justestd::swap()
m_size
etm_value
, et de l'utiliser ala:C'est facile et propre, mais il a un couple mineurs de la performance/les problèmes d'efficacité:
maintien de l'existant
m_value
tableau plus longtemps que nécessaire, ce qui augmente utilisation maximale de la mémoire... on pourrait appelerclear()
. Dans la pratique, la plupart des non-trivial programmes ne se soucient pas de cela, sauf si la structure de données en question a été la tenue d'énormes quantités de données (par exemple, des centaines de méga-octets ou giga-octets pour une application PC).de ne même pas essayer de réutiliser l'existant
m_value
de mémoire au lieu de toujours faire un autrenew
pourother
(qui peut mener à la réduction de l'utilisation de la mémoire mais n'est pas toujours utile).En fin de compte, les raisons, il peut être distinct du constructeur de copie et l'
operator=
- plutôt que de demander au compilateur de créer automatiquement l'un de l'autre -, c'est que de manière optimale efficace des implémentations ne peut pas - en général - l'effet de levier les uns des autres dans la façon dont vous l'auriez espéré.OriginalL'auteur Tony Delroy
La déclaration
FeatureValue(other);
appelle en fait le constructeur de copie pour créer une nouvelle Featurevalue objet,qui n'a rien à voir avec*this
.OriginalL'auteur witrus