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{"ola.normann@norge.no"};
std::unique_ptr<Car> car{new Car{5}};
Person a{name, mail, std::move(car)};
};
>Solution :
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{"ola.normann@norge.no"};
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)};
};