Comment éviter d'appeler explicitement un constructeur lors du passage d'objet temporaire par référence en C ++?

StackOverflow https://stackoverflow.com/questions/1008272

  •  06-07-2019
  •  | 
  •  

Question

Disons que j'ai un cours:

class String
{
public:
     String(char *str);
};

Et deux fonctions:

void DoSomethingByVal(String Str);
void DoSomethingByRef(String &Str);

Si j'appelle DoSomethingByVal comme ceci:

DoSomethingByVal("My string");

le compilateur comprend qu'il doit créer un objet String temporaire et appeler le constructeur char *.

Toutefois, si j'essaie d'utiliser DoSomethingByRef de la même manière, le message "Impossible de convertir le paramètre de" char * "en" String & amp; " erreur.

À la place, je dois créer explicitement une instance:

DoSomethingByRef(String("My string"));

ce qui peut vous inquiéter.

Y a-t-il un moyen d'éviter cela?

Était-ce utile?

La solution

Vous devez passer par référence de const:

Pour:

void DoSomethingByVal(String Str);

Dans cette situation, le compilateur crée d'abord une variable temporaire. Ensuite, la variable temporaire est construite dans le paramètre.

Pour:

void DoSomethingByRef(String const& Str);

Dans cette situation, le compilateur crée une variable temporaire. Mais les variables temporaires ne peuvent pas être liées à une référence, elles ne peuvent l'être qu'à une référence const. Par conséquent, votre fonction d'origine ne peut pas être appelée. Notez que le constructeur d’objets std :: string prend une référence const comme paramètre du constructeur de copie et c’est pourquoi la première version fonctionne comme le temporaire est lié au paramètre de référence const du constructeur de copie uniquement.

Autres conseils

Hmm, je ne suis pas sûr si

void DoSomethingByRef(String &Str);
DoSomethingByRef(String("My string"));

compilerait réellement. Une valeur rvalue ne peut pas être liée à une référence à non-const (car une référence à non-const indique que vous modifierez la valeur et qu'il ne serait pas logique de modifier une valeur temporaire). Êtes-vous sûr de ne pas faire:

String str("My string");
DoSomethingByRef(str);

Si vous voulez que DoSomethingByVal prenne une valeur rvalue, le paramètre doit être une référence à const:

void DoSomethingByRef(const String &Str);

Marque:

Faites quelque choseByRef (const String & amp; str);

" Ma chaîne " n'est pas une chaîne, c'est une c-string, un char *, si vous voulez. Vous devez placer cette chaîne de caractères dans un objet String, puis vous pouvez transmettre le nouvel objet String par référence.

Autre point, vous passez déjà un caractère * ... assez léger, juste un pointeur. Pourquoi s'inquiéter de passer un nouvel objet par référence? Allouez simplement un nouvel objet à l'intérieur de ce constructeur à partir du tas et copiez-y la chaîne c.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top