C ++ конструктор со списком аргументов - PullRequest
1 голос
/ 02 апреля 2020

Я знакомлюсь с конструкторами в C ++ и удивляюсь, почему мой компилятор C ++ не может найти конструктор со списком аргументов.

#include <cstdio>
#include <string>

const int defaultAge = 0;
const std::string unknown = "unknown";

class Patient {

    public:
     int age;
     std::string dob;
     std::string name;

    public:
     Patient();                                                           // Default Constructor
     Patient(int &years, std::string &birthdate, std::string &aliase);    // Argument-List Constructor
     void print();
};

Patient::Patient() : age(defaultAge), dob(unknown), name(unknown) {
    puts("Patient information from default consturctor:");
}

Patient::Patient(int &years, std::string &birthdate, std::string &aliase) 
: age(years), dob(birthdate), name(aliase) {
    puts("Patient information from copy consturctor:");
}

void Patient::print() {
    printf(" Name - %d\n DOB  - %s\n Name - %s\n", age, dob.c_str(), name.c_str());
}

int main(void) {

    Patient p0;
    p0.print();

    Patient p1(40, "August 11, 1980", "John Doe");
    p1.print();

    return 0;
}

Я получаю следующую ошибку при попытке скомпилировать код:

ошибка компиляции

Я использую Apple Clang версии 11.0.0 в качестве моего компилятора

Ответы [ 2 ]

2 голосов
/ 02 апреля 2020

Вы объявляете параметры как lvalue-ссылку на non-const, которая не может быть привязана к r-значениям, таким как 40 (который является литералом int), "August 11, 1980" и "John Doe" (которые являются строкой литералы и будут преобразованы в std::string неявно как временные значения, которые являются rvalues).

Вы можете сделать их lvalue ссылкой на const (как для объявления, так и для определения), например,

Patient(const int &years, const std::string &birthdate, const std::string &aliase);
//      ^^^^^             ^^^^^                         ^^^^^

Или для int просто сделайте передачу по значению.

Patient(int years, const std::string &birthdate, const std::string &aliase);
//      ^^^        ^^^^^                         ^^^^^

LIVE

1 голос
/ 02 апреля 2020

songyuanyao указывает на проблему с вашим кодом. Хорошей альтернативой является передача по значению, а затем перемещение:

Patient::Patient(int &years, std::string birthdate, std::string aliase) 
    : age(years), dob(std::move(birthdate)), name(std::move(aliase))
{
    puts("Patient information from copy consturctor:");
}

В исходном коде (или исправлении songyuanyao) каждое содержимое строки выделяется дважды, тогда как в этой версии есть одно распределение и одно перемещение.

Как правило, передавайте по значению каждый раз, когда функция собирается сохранить копию аргумента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...