Reputation: 11
I'm getting familiar with constructors in C++, and wondering why my C++ compiler can't find the constructor with an argument-list.
#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;
}
I get the following error when attempting to compile the code:
I'm using Apple clang version 11.0.0 as my compiler
Upvotes: 1
Views: 1600
Reputation: 172964
You're declaring the parameters as lvalue reference to non-const, which can't be bound to rvalues like 40
(which is an int
literal), "August 11, 1980"
and "John Doe"
(which are string literals and would be converted to std::string
implicitly as temporories, which are rvalues).
You can make them lvalue reference to const (for both the declaration and definition), e.g.
Patient(const int &years, const std::string &birthdate, const std::string &aliase);
// ^^^^^ ^^^^^ ^^^^^
Or for int
just make it pass-by-value.
Patient(int years, const std::string &birthdate, const std::string &aliase);
// ^^^ ^^^^^ ^^^^^
Upvotes: 2
Reputation: 141628
songyuanyao points out the problem with your code. A good alternative is to pass by value and then move:
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:");
}
In your original code (or songyuanyao's fix) then every string content is allocated twice , whereas in this version there is one allocation and one move .
As a rule of thumb, pass by value any time that the function is going to store a copy of the argument.
Upvotes: 1