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)};
};
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)};
};
Related
I need to get in a vector the names of some cities as soon as they are created... In order to accomplish that I created a static vector for the class City, however when I try to compile my code I get the error
error: lvalue required as unary '&' operand
this->cities.push_back(&this);
^~~~
What am I doing wrong?
My code is the following...
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
class City
{
private:
string name;
static vector<City *> cities;
public:
string getName() { return name; }
City(string name) : name{name}
{
this->cities.push_back(&this);
};
~City(){};
} hongKong{"Hong Kong"}, bangkok{"Bangkok"}, macau{"Macau"}, singapura{"Singapura"}, londres{"Londres"}, paris{"Paris"}, dubai{"Dubai"}, delhi{"Delhi"}, istambul{"Istambul"}, kuala{"Kuala"}, lumpur{"Lumpur"}, novaIorque{"Nova Iorque"}, antalya{"Antalya"}, mumbai{"Mumbai"}, shenzen{"Shenzen"}, phuket{"Phuket"};
int main()
{
}
this is already a City* pointer, so drop the & from &this.
Also, don't forget to actually define the static vector object.
Also, you should account for the class' copy/move constructors and destructor, to make sure you don't miss adding pointers, or leave behind dangling pointers.
Try this:
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
class City
{
private:
string name;
static vector<City *> cities;
public:
string getName() { return name; }
City(string name) : name{name}
{
cities.push_back(this);
}
City(const City &src) : name{src.name}
{
cities.push_back(this);
}
City(City &&src) : name{std::move(src.name)}
{
cities.push_back(this);
}
~City()
{
cities.erase(std::find(cities.begin(), cities.end(), this));
}
};
vector<City *> City::cities;
City hongKong{"Hong Kong"}, bangkok{"Bangkok"}, macau{"Macau"}, singapura{"Singapura"}, londres{"Londres"}, paris{"Paris"}, dubai{"Dubai"}, delhi{"Delhi"}, istambul{"Istambul"}, kuala{"Kuala"}, lumpur{"Lumpur"}, novaIorque{"Nova Iorque"}, antalya{"Antalya"}, mumbai{"Mumbai"}, shenzen{"Shenzen"}, phuket{"Phuket"};
int main()
{
}
I have a problem with c++ derived class constructor , I looked everywhere for similar problems but I dont seem to find any , I wish I will fin help in here.
basically I have a base classe with a constructor that has 4 parameters , and I derived a class from that base class but this time it has 6 parameters ,
both constructors are defined in a cpp file .
here are my files (in frensh):
**Entraineur.h**
class Entraineur: public Personne {
public:
Entraineur(std::string p_nom, std::string p_prenom, util::Date p_date, std::string p_num, std::string
m_numRAMQ, std::string m_sexe);
virtual ~Entraineur();
private:
std::string m_prenom;
std::string m_nom;
util::Date m_dateNaissance;
std::string m_telephone;
std::string m_numRAMQ;
std::string m_sexe;
**Entraineur.cpp**
#include "Personne.h"
#include "Entraineur.h"
#include <string>
#include "Date.h"
Entraineur::Entraineur(std::string p_nom, std::string p_prenom, util::Date p_date, std::string p_num,
std::string m_numRAMQ, std::string m_sexe) {
}
Entraineur::~Entraineur() {
// TODO Auto-generated destructor stub
}
**Personne.h**
class Personne {
public:
Personne(std::string p_nom, std::string p_prenom, util::Date p_date, std::string p_num);
virtual ~Personne();
private:
std::string m_prenom;
std::string m_nom;
util::Date m_dateNaissance;
std::string m_telephone;
std::string m_numRAMQ;
std::string m_sexe;
};
**Personne.cpp**
Personne::Personne(std::string p_nom, std::string p_prenom, util::Date p_date, std::string p_num) {
// TODO Auto-generated constructor stub
//setters
asgNom(p_nom);
asgPrenom(p_prenom);
asgDateNaissance(p_date);
asgTelephone(p_num);
}
Personne::~Personne(){
std::cout<< "detruit";
}
all the #includes are there.
please I beg for help.
I have problem in defining constructors for classes and the way I have defined them earlier, doesn't work here properly.
This is for edx c++ intermediate course. when I try to define a class that inherits from some other class, referring to my base class with a constructor doesn't work properly and so my new class won't be defined correctly. What's the difference between the first use of constructors in the first code (using ":" notation that works properly), and the second one in second code (defining like function, that I have used before properly and doesn't work here)?
I have a base class called Person and a Student class that inherits from the base class. When I try to initialize a Student object that calls one of Person class constructors, it gives wrong answers. I think this is because of the way I define constructors. I make them like functions and initialize variables in curl braces. I have used this method earlier and it was working properly, but it doesn't work here. But the standard method using ":" before curly braces works properly here. I want to know what is the difference between these two?
Person.h:
#pragma once
#include <string>
class Person
{
private:
std::string name;
protected:
int age;
public:
Person();
Person(const std::string & name, int age);
void displayNameAge() const;
};
Person.cpp:
#include "pch.h"
#include "Person.h"
#include <iostream>
//Person::Person()
// : name("[unknown name]"), age(0)
//{
// std::cout << "Hello from Person::Person()" << std::endl;
//}
Person::Person()
{
name = "[unknown name]";
age = 0;
std::cout << "Hello from Person::Person()" << std::endl;
}
Person::Person(const std::string & name, int age)
{
this->name = name;
this->age = age;
std::cout << "Hello from Person::Person(string, int)" << std::endl;
}
//Person::Person(const std::string & name, int age)
// : name(name), age(age)
//{
// std::cout << "Hello from Person::Person(string, int)" << std::endl;
//}
void Person::displayNameAge() const
{
std::cout << name << ", " << age << std::endl;
}
Student.h:
#pragma once
#include "Person.h"
class Student : public Person
{
private:
std::string course;
public:
Student();
Student(const std::string & name, int age, const std::string & course);
void displayCourse() const;
};
Student.cpp:
#include "pch.h"
#include "Student.h"
#include <iostream>
Student::Student()
{
course = "[unassigned course]";
std::cout << "Hello from Student::Student()" << std::endl;
}
// first method: the right one
//Student::Student(const std::string & name, int age, const std::string & course)
// : Person(name, age), course(course)
//{
// std::cout << "Hello from Student::Student(string, int, string)" << std::endl;
//}
// second method: the wrong one
Student::Student(const std::string & name, int age, const std::string & course)
{
Person(name, age);
this->course = course;
std::cout << "Hello from Student::Student(string, int, string)" << std::endl;
}
void Student::displayCourse() const
{
std::cout << course << std::endl;
}
Main.cpp:
#include "pch.h"
#include "Student.h"
int main()
{
// Create a Student object using the no-argument constructor.
Student Student1;
Student1.displayNameAge();
Student1.displayCourse();
// Create a Student object using the parameterized constructor.
Student Student2("Jane Smith", 25, "Physics");
Student2.displayNameAge();
Student2.displayCourse();
return 0;
}
expected result:
Hello from Person::Person()
Hello from Student::Student()
[unknown name], 0
[unassigned course]
Hello from Person::Person(string, int)
Hello from Student::Student(string, int, string)
Jane Smith, 25
Physics
actual result:
Hello from Person::Person()
Hello from Student::Student()
[unknown name], 0
[unassigned course]
Hello from Person::Person()
Hello from Person::Person(string, int)
Hello from Student::Student(string, int, string)
[unknown name], 0
Physics
Initializer List
What you are missing is the initializer list.
Type::Type(Parameters)
: member1(init) // This is the initializer list
, member2(init)
{
Your code
}
If you do not explicitly provide one then the compiler will do it for you using the default constructor for the parent class then a call to the default constructor for each member.
So lets look at your class.
Student::Student(const std::string & name, int age, const std::string & course)
{
// Code
}
That is what you wrote. But this is what the compiler implemented.
Student::Student(const std::string & name, int age, const std::string & course)
: Person()
, course()
{
// Code
}
So because you did not do anything the compiler added it calls to the Person default constructor and course (std::string) default constructor.
Now the problem comes if your base class does not have a default constructor. Then the compiler can not add the appropriate calls and will generate a compiler error.
But there is also the issue that the way you are writing this is very inefficient as you are basically initializing all the members twice. Your calling the default constructor then in the Code section you are re-initializing the members with another value.
Student::Student(const std::string & name, int age, const std::string & course)
: Person(name, age)
, course() // Initialize it to empty here.
{
course = "[unassigned course]"; // Re-Initialize it with info.
}
You could simply do it once:
Student::Student()
: Person() // Note person must have a default constructor for this to work.
, course("[unassigned course]")
{}
Temporary Object
Student::Student(const std::string & name, int age, const std::string & course)
{
Person(name, age);
// CODE.
}
This is not doing what you think.
Lets add the initializer list.
Student::Student(const std::string & name, int age, const std::string & course)
: Person()
, course()
{
Person(name, age); // This is creating a person object localy.
// the person object has no name so is a
// temporary variable and goes out of scope
// at the ';'. So it is created and destroyed
// in place before other code is executed.
//
// This does not help initialize the class.
// It is creating a completely different
// and independent object.
// CODE.
}
You can see the execution here:
Hello from Person::Person() // Init parent
Hello from Person::Person(string, int) // Init the temp object.
// If you put a print in the destructor
// You will also see that executed
// Before the Student
// This is also why the object has "unknown name" and 0 age.
Hello from Student::Student(string, int, string) // Now we init the student
[unknown name], 0
Physics
Advice
Is there a valid scenario where you want initialized versions of the object? Personally I think not (if there are then ignore this) so get rid of the default constructors of Person and Student. Then you can not create uninitialized Students or `People.
I got two classes, one named Person that I checked is working (I can create objects of that class so the problem should not be here).
I then have another class called Family with composition from Person:
Family.h
#include "Person.h"
class Family
{
public:
Family();
void printFamily();
private:
Person dad_();
Person mum_();
Person son_();
Person daughter_();
};
Family.cpp
#include "Family.h"
Family::Family()
{
}
void printFamily()
{
dad_.printAll();
mum_.printAll();
son_.printAll();
daughter_.printAll();
//printAll() is a function in the Person class that worked when
//I tested it earlier with only the person class
}
But when i try to compile this I get an error:
left of '.printAll' must have class/struct/union
'son_' : undeclared identifier
This error goes for all the .printAll() calls in family.cpp.
I can't see why this wouldn't work, so I hope you can.
Edit1:
Ok i changed
void printFamily()
to
void Family::printFamily()
That removes one error, but i still get
left of '.printAll' must have class/struct/union
Edit2
Ah my bad with the Person calls i changed them to
Person dad_;
and the same with the rest.
Seems like their might be an error with my Person class so i will post that also
Person.h
#include <string>
using namespace std;
class Person
{
public:
Person( const string & = "000000-0000", const string & = "N", const string & = "",const string & = "N");
~Person();
void setFirstName(const string &);
void setMiddleName(const string &);
void setLastName(const string &);
void getData(string &,string &,string &,string &);
static int getNumberOfPersons();
void printPartially() const;
void printAll() const;
bool checkForSameName(const Person &);
private:
string firstName_;
string middleName_;
string lastName_;
string socialSecNumber_;
static int numberOfPersons_;
};
Person.cpp
#include "Person.h"
#include <iostream>
int Person::numberOfPersons_ = 0;
Person::Person( const string &sNumber, const string &firstName, const string &middleName,const string &lastName )
:firstName_(firstName),middleName_(middleName),lastName_(lastName),socialSecNumber_(sNumber)
{
numberOfPersons_ ++;
}
Person::~Person()
{
numberOfPersons_--;
}
void Person::setFirstName(const string &firstName)
{ firstName_ = firstName; }
void Person::setMiddleName(const string &middleName)
{ middleName_ = middleName; }
void Person::setLastName(const string &lastName)
{lastName_ = lastName;}
void Person::getData(string &fName,string &mName,string &lName,string &sNumber)
{
fName = firstName_;
mName = middleName_;
lName = lastName_;
sNumber = socialSecNumber_;
}
int Person::getNumberOfPersons()
{
return numberOfPersons_;
}
void Person::printPartially() const
{
cout <<"Navn: "<<firstName_<<" "<<middleName_<<" "<<lastName_<<endl;
cout <<"Født: ";
for (int i = 0;i<6;i++)
{
cout <<socialSecNumber_.at(i);
}
}
void Person::printAll() const
{
cout <<"Navn: "<<firstName_<<" "<<middleName_<<" "<<lastName_<<endl;
cout <<"Personnr: "<<socialSecNumber_<<endl;
}
bool Person::checkForSameName(const Person &p)
{
if (p.firstName_ == firstName_ && p.middleName_ ==middleName_ && p.lastName_ == lastName_)
return true;
else
return false;
}
Now i am getting some new errors:
error C2011: 'Person' : 'class' type redefinition
see declaration of 'Person'
'Family::dad_' uses undefined class 'Person'
The "dad" error applies to the whole family
You have a few syntax issues.
First, you're declaring each of what are supposed to be member variables as functions which return Person. They should look like (note, no parens):
Person dad_;
Person mum_;
Person son_;
Person daughter_;
You're also missing the scoping on your definition of printFamily:
void Family::printFamily() {
...
}
Without the preceding Family::, C++ thinks you're defining a free function, and doesn't know to look inside the Family class for the declarations of dad_, mum_, etc.
Additionally, at least with the code you've shown, there's no way to initialize the people in your class. The Family constructor should take arguments to define the people, or you should have setters which allow defining them later. Right now, you'll get 4 identical people, set up however the default person constructor builds them.
I would normally prefer the constructor method, but I have other design reservations about your code to begin with (e.g. Does a family always contain mum, dad, brother, sister?) and that's not really what this question is about.
The line:
Person dad_();
says that dad_ is a function that returns a Person, not an object. Did you mean that? Similarly for others.
Try
Person dad_;
Family.h
#include "Person.h"
class Family
{
public:
Family();
void printFamily();
private:
Person dad_;
Person mum_;
Person son_;
Person daughter_;
};
Family.cpp
#include "Family.h"
Family::Family()
{
}
void Family::printFamily()
{
dad_.printAll();
mum_.printAll();
son_.printAll();
daughter_.printAll();
//printAll() is a function in the Person class that worked when
//I tested it earlier with only the person class
}
The out of line definition of a member function needs to include the class name:
void Family::printFamily()
{
//...
Surprisingly, you already got this right for the constructor but then immediately forgot...
Second, your private class members are functions, not data members (which is odd), but if that's deliberate, you need to call them:
dad_().printAll();
// ^^^
I'm having an error with my constructor in my classes.
In my .cpp file I've got:
Player::Player()
{
m_name="Jane";
m_amt=100;
}
and in my .h file I've got:
// Default constructor, does nothing.
Player();
// Creates a Player. Player name and amount.
Player(const char &name, int amt);
I'm getting the error:
error: invalid conversion from ‘const char*’ to ‘char’ [-fpermissive]
m_name="Jane";
So I tried converting it to a *char but that still doesn't work. Can someone help please?
You can either take a pointer:
Player(const char* name, int amt) { ... }
and you could use std::string to store the name and use char* just to construct this string:
private:
std::string m_name;
public:
Player(const char* name, int amt) : m_name(name) { }
or just use std::string everywhere and pass by reference to avoid redundant copies being created:
private:
std::string m_name;
public:
Player(const std::string& name, int amt) : m_name(name) { }
Note that the last version is quite flexible and it's possible to also pass const char* to it, example:
#include <iostream>
#include <string>
class Player {
private:
std::string m_name;
public:
Player(const std::string& name) : m_name(name){}
void printName() { std::cout << m_name; }
};
int main() {
Player p("Liho");
p.printName();
}
Show your full class/code. Following compiles fine for me.
cpp file...
#include"player.h"
Player::Player()
{
m_name="Jane";
m_amt=100;
}
.h file...
class Player {
public:
// Default constructor, does nothing.
Player();
// Creates a Player. Player name and amount.
Player(const char *name, int amt);
private:
char* m_name;
int m_amt;
};