Je me demande si ce bit de code présente le bon comportement C++?Comportement correct de l'opérateur conditionnel dans VS2010?
class Foo
{
public:
Foo(std::string name) : m_name(name) {}
Foo(const Foo& other) {
std::cout << "in copy constructor:" << other.GetName() << std::endl;
m_name = other.GetName();
}
std::string GetName() const { return m_name; }
void SetName(std::string name) { m_name = name; }
private:
std::string m_name;
};
Foo CreateFoo(std::string name)
{
Foo result(name);
return result;
}
void ChangeName(Foo& foo)
{
foo.SetName("foofoo");
}
int _tmain(int argc, _TCHAR* argv[])
{
Foo fooA("alan");
std::cout << "fooA name: " << fooA.GetName() << std::endl;
bool b = true;
ChangeName(b ? fooA : CreateFoo("fooB"));
std::cout << "fooA name: " << fooA.GetName() << std::endl;
return 0;
}
Une fois construit en VS2008 la sortie est:
fooA name: alan
fooA name: foofoo
Mais quand le même code est construit en VS2010 il devient:
fooA name: alan
in copy constructor: alan
fooA name: alan
Un constructeur de copie est invoquée sur « alan 'et, bien qu'il soit passé par référence (ou non selon le cas), fooA est inchangé par l'appelé à ChangeName
. La norme C++ a-t-elle changé, a-t-elle corrigé un comportement incorrect ou a-t-elle introduit un bogue? Par ailleurs, pourquoi le constructeur de copie est-il appelé?
Votre code me semble mal formé, donc je ne m'attends pas à ce qu'il y ait une réponse à vos questions à ce sujet. Vous attendez une référence en tant que param à ChangeName mais lui donner une expression qui crée un temporaire. –
Oui. Amenez le niveau d'avertissement à 4 et compilez à nouveau. –
@Noah: Ou désactiver les extensions de langue dans le compilateur VC, qui émettra une erreur de compilation qui dit exactement quel est le problème: 'error C2664: 'ChangeName': ne peut pas convertir le paramètre 1 de 'Foo' à 'Foo &'' –