Unfit function signature : the following code still compiles. How is it possible? [duplicate]
![Unfit function signature : the following code still compiles. How is it possible? [duplicate]](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2F80wy3gkl%2Fproduction%2F54e30bbcb677f725db7afda2ea2f51db97c37e46-1201x631.png&w=3840&q=75)
Let's have 3 files :
- Personne.h :
#include <iostream>
#include <string>
using namespace std;
struct Personne {
string nom;
string prenom;
int age;
Personne();
Personne(string nom, string prenom, int age);
Personne(Personne const*);
virtual ~Personne();
void set(Personne);
};
- Personne.cpp :
#include "Personne.h"
Personne::Personne() : nom(NULL) {}
Personne::Personne(string nom0, string prenom0, int age0) :
nom(nom0),
prenom(prenom0),
age(age0)
{}
Personne::Personne(Personne const* copied) :
nom(copied->nom),
prenom(copied->prenom),
age(copied->age)
{}
Personne::~Personne() {}
void Personne::set(Personne copied) {
cout << "copied.nom = " << copied.nom << endl;
nom = copied.nom;
prenom = copied.prenom;
age = copied.age;
}
- main.cpp :
#include "Personne.h"
int main()
{
cout << "Dinguerie !" << endl;
Personne moi("Gustin", "Didier", 34);
Personne* moi_pointeur(&moi);
moi_pointeur->set(moi_pointeur);
moi_pointeur->set(*moi_pointeur);
return 0;
}
In main.cpp, line 8 should generate a compilation error as it doesn't fit the signature of the function declared in Personne.h and implemented in Personne.cpp. Line 8 uses the set function with Personne* instead of Personne as argument. But no error at compilation and moreover line 8 do exactly the same as the line 9 at execution.
Can someone explain to me why this code compiles ?
Answer
C++ allows one implicit conversion per argument when matching function arguments, as Personne(Personne const*)
isn't marked explicit
it is used to convert your Personne*
to a new Personne
object.
moi_pointeur->set(moi_pointeur);
is automatically transformed to moi_pointeur->set(Personne(moi_pointeur));
Changing your class to:
struct Personne {
string nom;
string prenom;
int age;
Personne();
Personne(string nom, string prenom, int age);
explicit Personne(Personne const*);
virtual ~Personne();
void set(Personne);
};
results in the compiler error you expect.
In general it's a good idea to mark all single argument constructors as explicit
unless you want automatic conversions to apply.