I want my code to take a name
, mail
and car
as argument types, and I try to do so in a class named Person
. In main()
, I try to give that class a variable a
which I can call later in cout
. However, I get this exact error:
no matching constructor for initialization of "Person"
How can I fix this?
The h. file
#pragma once
#include <iostream>
#include "car.h"
#include <string>
class Person{
private:
std::string name;
std::string mail;
Car* car;
public:
Person(std::string name, std::string mail);
Person(std::string name, std::string, Car* car);
void setMail(std::string mail);
std::string getMail() const;
std::string getName() const;
bool hasAvailableFreeSeats();
friend std::ostream& operator <<(std::ostream& os, const Person& person);
};
The cpp file:
#include "person.h"
std::string Person:: getMail() const{
return mail;
}
std:: string Person:: getName() const{
return name;
}
void Person:: setMail(std::string mail){
this -> mail = mail;
}
Person:: Person(std::string name, std::string mail) : Person(name, mail, nullptr){};
Person::Person(std::string name, std::string, Car* car) : name{name}, mail{mail}, car{car}{};
bool Person:: hasAvailableFreeSeats(){
if (car != nullptr){
return car-> hasFreeSeats();
}
}
std::ostream& operator <<(std::ostream& os, const Person& person){
return os << person.name << ": " << person.mail << "\n";
}
main:
#include "person.h"
int main(){
std::string name{"Ola Normann"};
std::string mail{"[email protected]"};
std::unique_ptr<Car> car{new Car{5}};
Person a{name, mail, std::move(car)};
};
CodePudding user response:
First off, you have a typo in your 3-parameter Person
constructor. The 2nd parameter has no name assigned to it, so you end up initializing the mail
class member with itself, not with the caller's input:
Person::Person(std::string name, std::string, Car* car) : name{name}, mail{mail}, car{car}{};
^ no name here! ^ member!
That should be this instead:
Person::Person(std::string name, std::string mail, Car* car) : name{name}, mail{mail}, car{car}{};
^ has a name now! ^ parameter!
Now, that being said, your main()
code is passing 3 values to the Person
constructor:
Person a{name, mail, std::move(car)};
Your Person
class only has 1 constructor that accepts 3 parameters:
Person(std::string name, std::string, Car* car);
In main()
, your name
and mail
variables are std::string
objects, which is fine, but your car
variable is a std::unique_ptr<Car>
object, not a Car*
pointer. std::move(car)
will return a std::unique_ptr<Car>&&
rvalue reference, which Person
does not accept, hence the compiler error. std::unique_ptr
is not implicitly convertible to a raw pointer. You would have to use its get()
method instead:
Person a{name, mail, car.get()};
Which defeats the purpose of using std::unique_ptr
in the first place. You should instead change the Person
class to hold a std::unique_ptr
object instead of a raw pointer, eg:
.h
#pragma once
#include <iostream>
#include <string>
#include <memory>
#include "car.h"
class Person{
private:
std::string name;
std::string mail;
std::unique_ptr<Car> car;
public:
...
Person(std::string name, std::string mail);
Person(std::string name, std::string mail, std::unique_ptr<Car> car);
...
};
.cpp
#include "person.h"
...
Person::Person(std::string name, std::string mail) : Person(name, mail, nullptr){};
Person::Person(std::string name, std::string, std::unique_ptr<Car> car) : name{name}, mail{mail}, car{std::move(car)}{};
...
main
#include "person.h"
int main(){
std::string name{"Ola Normann"};
std::string mail{"[email protected]"};
std::unique_ptr<Car> car{new Car{5}};
Person a{name, mail, std::move(car)};
// alternatively:
// Person a{name, mail, std::make_unique<Car>(5)};
};