Context: I'm at the second year of Uni and we started using classes and understanding of creating some little applications. I'm building an employer class, every employer has 4 parameters: serial_number, name, surname, earnings and then there also junior and senior employers, with all the above but other parameters too. For example junior employers have a set of skills and intern: first one is a list of skills that a junior can have and the second is at which senior employer they are assigned.
ex. Junior with serial_number3 is the intern of Senior with serial_number1
NOW: I make use of the employer.h for the easy stuff, but when I get into declaring the list skills I just didn't understand what I should do.
#ifndef JUNIOR_H
#define JUNIOR_H
#include "employer.h"
#include <list>
using namespace std;
class junior : public employer
{
public:
junior(string serial, string name, string surname, double earns, list<string> sk, string in)
: employer(serial, name, surname, earns), skills(sk), intern(in) {}
list<string> getSkills() const { return skills; }
string getIntern() const { return intern; }
private:
list<string> skills;
string intern;
};
#endif // JUNIOR_H
if I try to write this in the main, it gives me now "no matching constructor for initialization of junior" and I have included the header
junior j("serial3", "name1" , "sur1", 3931, "cpp", "serial1");
The problem is, that the constructor expects as the 5th parameter a list<string>. You are just handing in a normal string "cpp".
You can simply add a braced initializer list as the 5th parameter. In your case, just with one string only: "cpp". This will create a list with one member "cpp".
I also recommend qualifying your parameter as const reference. This will avoid a lot of copying.
Then your program looks like the following and will compile.
#include <list>
#include <string>
using namespace std::string_literals;
using namespace std;
struct employer {
string serial{};
string name{};
string surname{};
double earns{};
employer(const string& serialp, const string& namep, const string& surnamep, const double earnsp) :
serial(serialp), name(namep), surname(surnamep), earns(earnsp) {};
};
class junior : public employer
{
public:
junior(const string& serial, const string& name, const string& surname, const double earns, const list<string>& sk, const string& in)
: employer(serial, name, surname, earns), skills(sk), intern(in) {}
list<string> getSkills() const { return skills; }
string getIntern() const { return intern; }
private:
list<string> skills;
string intern;
};
int main() {
junior j("serial3"s, "name1"s, "sur1"s, 3931, { "cpp"s }, "serial1"s);
}
Using using namespace std; for small demo projects is ok. Later you should definitely avoid that.
I used also string_literals. With that "Hello World"swill be of type string
simply write "junior("serial3", "name1" , "sur1", 3931, "cpp", "serial1");" not
"junior j("serial3", "name1" , "sur1", 3931, "cpp", "serial1");".......why are u writing j with it???
Related
I have been looking in different threads with this error which is quite common but it feels like the IDE I am using messed with my workspace and I can't quite find the problem. I am setting up an extremely basic class called "Movie" that is specified below:
Movie.hpp :
#ifndef MOVIE_HPP
#define MOVIE_HPP
#include <iostream>
#include <string>
using std::string, std::cout,std::size_t;
class Movie
{
private:
std::string name;
std::string rating;
int watched_ctr;
public:
Movie(const string& name, const string& rating, int watched_ctr);
~Movie();
//getters
string get_name() const;
string get_rating() const;
int get_watched() const;
//setters
void set_name(string name);
void set_rating(string rating);
void set_watched(int watched_ctr);
};
#endif // MOVIE_HPP
Movie.cpp:
#include <iostream>
#include <string>
#include "Movie.hpp"
using std::string, std::cout,std::size_t,std::endl;
Movie::Movie(const string& name, const string& rating, int watched_ctr)
: name(name) , rating(rating) , watched_ctr(watched_ctr) {
}
Movie::~Movie()
{
cout << "Destructor for Movies class called /n";
}
//Getters
string Movie::get_name(){return name;}
string Movie::get_rating(){return rating;}
string Movie::get_watched(){return watched_ctr;}
//Setters
void Movie::set_name(std::string n){this -> name = n;}
void Movie::set_rating(std::string rating){this -> rating = rating;}
void Movie::set_watched(int ctr){this -> watched_ctr = ctr;}
The main.cpp I am trying only consists in creating one Movie object:
#include <iostream>
#include <string>
#include "Movie.hpp"
using std::string, std::cout,std::size_t,std::endl;
int main()
{
Movie StarTrek("Star Trek", "G", 20);
}
As you can see, I set all the attribute to private in order to exercise with the set/get methods but I keep stumbling upon the same error on each of them stating >"C:/Users/.../ProjectsAndTests/MoviesClass/Movie.cpp:18:8: error: no declaration matches 'std::__cxx11::string Movie::get_name()"
if you could give me a hint on what might cause this error I would greatly appreciate thank you!
I tried opening another workspace with classes implemented inside of them and the syntax I am using is very close from this test workspace I opened which compiled fine (no error regarding declaration match).
There are 2 problems with your code.
First while defining the member functions outside class you're not using the const. So to solve this problem we must use const when defining the member function outside the class.
Second, the member function Movie::get_watched() is declared with the return type of string but while defining that member function you're using the return type int. To solve this, change the return type while defining the member function to match the return type in the declaration.
//----------------------vvvvv--------->added const
string Movie::get_name()const
{
return name;
}
string Movie::get_rating()const
{
return rating;
}
vvv------------------------------>changed return type to int
int Movie::get_watched()const
{
return watched_ctr;
}
Working demo
I'm currently working on an assignment to expand on a program we previously made, involving the use of header files, and parent classes. In the original, I have 2 header files. Person.h, and OCCCDate.h. In the new one, I am creating one called OCCCPerson.h. It's an incredibly simple class that basically just uses Person, just with 1 added variable.
My problem is, I cant figure out how to use the parent constructor properly.
Here is the Person.h file.
#ifndef PERSON_H
#define PERSON_H
#include <string>
#include "OCCCDate.h"
using namespace std;
class Person{
private:
string firstName;
string lastName;
OCCCDate dob;
public:
Person();
Person(string, string);
Person(string, string, OCCCDate);
string getFirstName();
string getLastName();
void setFirstName(string);
void setLastName(string);
int getAgeInYears();
bool equals(Person);
string toString();
};
#endif
And here is my OCCCPerson.h file
#ifndef OCCCPERSON_H
#define OCCCPERSON_H
#include <string>
#include "OCCCDate.h"
#include "Perosn.h"
using namespace std;
class OCCCPerson : Person{
protected:
string studentID;
public:
OCCCPerson(string firstName, string lastName, OCCCDate dob, string studentID);
OCCCPerson(Person p, string studentID);
string getStudentID();
bool equals(OCCCPerson p);
string toString();
};
#endif;
I cant seem to call on the parents constructor to get things like the firstname, lastname, and dob(date of birth). From my handout, it says the parent constructor has to be initialized with, : Person(parameters), where parameters are things in the parent class. However, I have no idea where to put that. Sorry for writing so much. I just couldn't figure out how to shrink that down.
Oh, and here is OCCCDate.h just in case
#ifndef OCCCDATE_H
#define OCCCDATE_H
#include<string>
using namespace std;
class OCCCDate{
private:
bool OCCCDate_US;
bool OCCCDate_EURO;
int dayOfMonth, monthOfYear, year;
bool dateFormat;
public:
OCCCDate();
OCCCDate(int dayOfMonth, int monthOfYear, int year);
int getDayOfMonth();
int getMonth();
string getNameOfMonth();
int getYear();
string getDate();
int getDifference(OCCCDate d1, OCCCDate d2);
int getDifference(OCCCDate d1);
void setDateFormat(bool);
bool equals(OCCCDate d);
string toString();
};
#endif
And here is my OCCCDate.cpp file
#include<iostream>
#include<ctime>
#include "OCCCPerson.h"
using namespace std;
OCCCPerson::OCCCPerson(string firstName, string lastName, OCCCDate dob, string studentID):Person(firstName, lastName, dob){
string firstName = Person::getFirstName();
string lastName = Person::getLastName();
OCCCDate dob = dob;
this->studentID = studentID;
}
OCCCPerson::OCCCPerson(Person p, string studentID){
Person p = p;
this->studentID = studentID;
}
What you need is member initializer lists.
From cppreference:
In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual base subobjects and non-static data members.
A simple example:
class MyClass : BaseClass
{
public:
MyClass(int arg) : BaseClass(arg) {
//Rest of code
}
}
In your case, you can do:
OCCCPerson(string firstName, string lastName, OCCCDate dob, string studentID) :
Person(firstName, lastName, dob) {
this.studentID = studentID;
}
In OCCCPerson.cpp,
OCCCPerson(string firstName, string lastName, OCCCDate dob, string
studentID) : Person(firstName, lastName, dob)
{
//more stuff
}
You basically have to use an initializer list.
Read more here: What are the rules for calling the superclass constructor?
What this does is it calls the parent constructor Person(string, string, OCCCDate) and basically performs this->firstName = firstName. Similarly for lastName and dob. But not studentID because the Person(string, string, OCCCDate) constructor doesn't provide initialization for studentID.
I want to create a object array of Accounts so I can manage them load everything from a file (by struct).
Im pretty new leaning c++ but I have no idea what I am doing wrong.
What does: Account** accounts[50] ?
"" accounts[i] = new Account*;
"" accounts[i]->newAccount(i, id_string, pw_string, level_int);
ERROR MESSAGE: request for member 'newAccount' in '* accounts[i]', which is of non-class type 'Account*'
AccountManagerFrm.cpp // Mainfile to run everything
#include "AccountManagerFrm.h"
#include "Account.h"
#include "ladeAccounts.h"
using namespace std;
Account** accounts [50];
void AccountManagerFrm::createAccountClick(wxCommandEvent& event)
{
accounts[i] = new Account*;
accounts[i]->newAccount(i, id_string, pw_string, level_int); // ERROR LINE
}
Account.cpp
class Account
{
struct iAccount
{
string ID;
string password;
int level;
};
Account()
{
}
void newAccount(int anzahl, string username, string pw, int lvl)
{
iAccount neu;
neu.ID = username;
neu.password = pw;
neu.level = lvl;
}
};
Account.h
#include <string>
using namespace std;
class Account{
public:
Account();
void newAccount(int anzahl, string username, string pw, int lvl);
void getInformationFromFile();
};
I want to create a object array of Accounts
That's just
Account accounts[50];
not your weird array of pointers to pointers. Then you can access one with .
accounts[i].newAccount(i, id_string, pw_string, level_int);
You'll also need to fix up the class definition. The definition itself, in the header, needs to contain all members. Also, the header should have a guard, to avoid errors if you include the header more than once. It's a bad idea to dump namespace std; into the global namespace; this pollutes the global namespace for everyone who includes the header. The whole header should be something like
#ifndef ACCOUNT_H
#define ACCOUNT_H
#include <string>
class Account {
public:
Account();
void newAccount(int anzahl, std::string username, string std::pw, int lvl);
void getInformationFromFile();
private:
std::string ID;
std::string password;
int level;
};
#endif
The source file should just define the member functions, not redefine the whole class:
#include "Account.h"
Account::Account() {}
void Account::newAccount(int anzahl, std::string username, std::string pw, int lvl)
{
ID = username;
password = pw;
level = lvl;
}
If you're struggling with basic class definitions, then you really should read a good introductory book. This is a complicated language, and you'll never learn it by guessing the syntax.
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 trying to create a member function that allows an user to set member array variables.
I've been looking everywhere but I can't find the problem in my code,
#include <string>
#include <iostream>
using namespace std;
class Employee
{
protected:
string name;
char ssn[11];
char id[5];
char hired[8];
public:
Employee(char ssn, char id, char hired); //Constructor
Employee(string name);
~Employee(); //Destructor
void setName(string n) { n = name; }
void setSSN(char i) { ssn = i; }
};
int main()
{
return 0;
}
Let's have a look at your setSSN function:
void setSSN(char i) { ssn = i; }
SNN, which most likely means social security number, doesn't consist of just one digit but 11, right? Then why would setSSN take as input only one character (digit) by (char i)? So setSSN function should rather take a string of characters containing SSN of the employee and that string should be of the same flavor as the ssn member variable of your Employee class in order to let you assign one string variable by another in the body of setSSN function. If you are already familiar with the string class of the C++ standard library, you should probably use that class for all your string storage and manipulation.