Home > Blockchain >  Why do I get a "no matching constructor error?
Why do I get a "no matching constructor error?

Time:03-24

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)};
};
  • Related