I've done the Harvard CS50 Course and worked with python a fair bit. I'm now doing a C++ course (Microsoft's) and the learning exercise has me creating a few classes. The exercise specifically tasks me to instantiate a few objects in main and return some values;
#include <iostream>
#include "School.h"
int main()
{
Student student1("Joe", "Bloggs", 31, "123 Fake Street", "London");
Student student2("Fred", "Adams", 24, "95 Something Avenue", "Manchester");
Student student3("John", "Doe", 90, "44a Old Man Lane", "Kettering");
Course course1("Introduction to Psychology");
course1.addStudent(student1);
course1.addStudent(student2);
course1.addStudent(student3);
Teacher teacher1("Helen", "Professorson", 48, "15 Teacher Way", "Kent");
course1.addTeacher(teacher1);
std::cout << course1.getCourseName() << std::endl;
teacher1.GradeStudent();
}
I'm using a header file and cpp file to define the classes, School.h:
#pragma once
#include <string>
class Person
{
public:
// Constructors and Destructors
Person();
Person(std::string, std::string); // First and Last Name
Person(std::string, std::string, int, std::string, std::string, std::string); // fName, lName, Age, Address, City, Phone
~Person();
// Member functions
std::string getFirstName();
void setFirstName(std::string);
std::string getLastName();
void setLastName(std::string);
int getAge();
void setAge(int);
std::string getAddress();
void setAddress(std::string);
std::string getCity();
void setCity(std::string);
std::string getPhone();
void setPhone(std::string);
private:
std::string _fName;
std::string _lName;
int _age;
std::string _address;
std::string _city;
std::string _phone;
};
class Student : public Person
{
public:
// Constructors and Destructors
// Member Functions
void SitInClass();
};
class Teacher : public Person
{
public:
// Member Functions
void SitInClass();
void GradeStudent();
};
class Course
{
public:
// Constructors and Desctructors
Course();
Course(std::string); // course name
~Course();
// Member functions
void addStudent(Student);
void addTeacher(Teacher);
// Getters and Setters
std::string getCourseName();
void setCourseName(std::string);
private:
// Member variables
std::string _courseName;
Student _students[30];
Teacher _teacher;
};
School.cpp:
#include "School.h"
#include <iostream>
#include <string>
// Constructors
Person::Person()
{
std::string _fName{};
std::string _lName{};
int _age{};
std::string _address{};
std::string _city{};
std::string _phone{};
}
Person::Person(std::string fName, std::string lName)
{
std::string _fName{ fName };
std::string _lName{ lName };
int _age{};
std::string _address{};
std::string _city{};
std::string _phone{};
}
Person::Person(std::string fName, std::string lName, int age, std::string address, std::string city, std::string phone)
{
std::string _fName{ fName };
std::string _lName{ lName };
int _age{ age };
std::string _address{ address };
std::string _city{ city };
std::string _phone{ phone };
}
// Destructor
Person::~Person()
{
}
std::string Person::getFirstName()
{
return this->_fName;
}
void Person::setFirstName(std::string fName)
{
this->_fName = fName;
}
std::string Person::getLastName()
{
return this->_lName;
}
void Person::setLastName(std::string lName)
{
this->_lName = lName;
}
int Person::getAge()
{
return this->_age;
}
void Person::setAge(int age)
{
this->_age = age;
}
std::string Person::getAddress()
{
return this->_address;
}
void Person::setAddress(std::string address)
{
this->_address = address;
}
std::string Person::getCity()
{
return this->_city;
}
void Person::setCity(std::string city)
{
this->_city = city;
}
std::string Person::getPhone()
{
return this->_phone;
}
void Person::setPhone(std::string phone)
{
this->_phone = phone;
}
void Student::SitInClass()
{
std::cout << "Sitting in main theater" << std::endl;
}
void Teacher::SitInClass()
{
std::cout << "Sitting at front of class" << std::endl;
}
void Teacher::GradeStudent()
{
std::cout << "Student Graded" << std::endl;
}
Course::Course()
{
Student* _students;
Teacher* _teacher;
std::string _name{};
}
Course::Course(std::string name)
{
Student* _students[30];
Teacher* _teacher;
std::string _name{ name };
}
Course::~Course()
{
}
void Course::addStudent(Student student)
{
// TODO: Loop through _students and insert new student in
}
void Course::addTeacher(Teacher teacher)
{
this->_teacher = &teacher;
}
std::string Course::getCourseName()
{
return this->_name;
}
void Course::setCourseName(std::string name)
{
this->_name = name;
}
I actually haven't been taught inheritance yet, but since both Student and Teacher needed the same variables (name, age, address etc.) I decided it'd be sensible.
Having a few problems though:
My instantiations of Student and Teacher in main.cpp aren't correct. I think because they are inheriting from Person(?). How do I create a constructor within these derived classes? I googled this but the solutions didn't seem to work.
The Course Class requires an array of Students. Do I have to specify a size of the array in the header file? It seems silly that I've specified 30 in both the header file and the cpp file, but VSstudio complains if I don't.
I'm using strings here. I have previously learned from a different course about char* and memory regarding strings. How many chars are assigned to all of these string class variables? If I instantiate a Students with name "Joe" and then want to later change his name to "Joseph" using student1.SetFirstName, is that going to cause segmentation faults?
Thanks, I figured it out mostly...
I needed to create constructors in Student and Teacher with the same input variables as the Person class, and then call the Person constructor in the Student consturctor:
Student::Student()
{
}
Student::Student(std::string fName, std::string lName)
: Person(fName, lName)
{
}
Student::Student(std::string fName, std::string lName, int age, std::string address, std::string city, std::string phone)
: Person(fName, lName, age, address, city, phone)
{
}
You do not need to specify array size in the constructor:
Header file looks like this:
class Course
{
...
private:
// Member variables
std::string _name;
Student* _students[30];
Teacher* _teacher;
};
And the constructor looks like this:
Course::Course()
: _students{ 0 }, _teacher{ 0 }, _name{}
{
}
To initialise every array item to 0.
Not so sure on still...
Related
I have some problem with overloading += operator
I want to add a item to vector (getAuthorList) with += operator
How can I do it in main ?
Code snippet (header file) :
class Author {
public:
Author(std::string firstName, std::string lastname, std::string affiliation);
std::string getFirstName();
std::string getLastName();
std::string getAffiliation();
void setFirstName(std::string);
void setLastName(std::string);
void setAffiliation(std::string);
void printFullName();
friend std::ostream& operator<<(std::ostream& output, const Author& author);
private:
std::string firstName;
std::string lastname;
std::string affiliation;
};
class Publication {
public :
Publication(std::string tiltle, Date publishDate, std::string publisher);
vector<Author> getAuthorList();
Author& operator+=(Author);
private:
vector<Author> authorList;
};
You can overload += operator like this
void operator+=(Author);
Change the operator return type to void as you are storing it in Publication class so it does not make any sense to return The same author from this operator.
you can write the operator definition like this
void Publication::operator+=(Author auth){
this->authorList.push_back(auth);
}
here is the working example:
#include <string>
#include <vector>
#include <iostream>
class Author {
public:
Author(const std::string& name):
Name(name){
}
const std::string& getName() const{
return Name;
}
private:
std::string Name;
};
class Publication {
public :
Publication(){
}
void operator+=(Author);
void getAuthorList(){
for (const auto& author: authorList){
std::cout << author.getName() << std::endl;
}
}
private:
std::vector<Author> authorList;
};
void Publication::operator+=(Author auth){
this->authorList.push_back(auth);
}
int main(){
Publication pub;
Author auth("Alice");
pub += auth;
Author auth2("Mark");
pub += auth2;
pub.getAuthorList();
}
Note: I just tried to make simple.
You could use the std::vector method called push_back inside the implementation block of your overloaded operator.
I have a class CPerson and I want to initialize a vector of type CPerson with object variables. However the compiler says that type name is not allowed. I would like to ask why is that?
class CPerson {
protected:
string m_strName;
Sex m_Sex;
Titles m_Title;
public:
CPerson() {
m_strName = "Peter Petrov";
m_Sex = male;
m_Title = bachelor;
}
//добавяме параметричен к-р
CPerson(string n,Sex s,Titles t) {
m_strName = n;
m_Sex = s;
m_Title = t;
}
~CPerson() {}
void SetName(string strName) {
m_strName = strName;
}
void SetSex(Sex sex) {
m_Sex = sex;
}
void SetTitle(Titles title) {
m_Title = title;
}
string GetName() const {
return m_strName;
}
};
int main(){
vector <CPerson> perr = { CPerson p1,
CPerson p2("I.Ivanov", male, professor),
CPerson p3("A.Stoyanova", female, assistant),
CPerson p4("A.Dimitrova", female, assistant)}
return 0;
}
There are a lot of problems in your code. Here is a version of the code that compiles successfully:
// Example program
#include <iostream>
#include <string>
#include <vector>
enum class Sex {
male, female
};
enum class Titles {
bachelor,
assistant,
professor
};
class CPerson {
protected:
std::string m_strName;
Sex m_Sex;
Titles m_Title;
public:
CPerson() {
m_strName = "Peter Petrov";
m_Sex = Sex::male;
m_Title = Titles::bachelor;
}
//добавяме параметричен к-р
CPerson(std::string n,Sex s,Titles t) {
m_strName = n;
m_Sex = s;
m_Title = t;
}
void SetName(std::string strName) {
m_strName = strName;
}
void SetSex(Sex sex) {
m_Sex = sex;
}
void SetTitle(Titles title) {
m_Title = title;
}
std::string GetName() const {
return m_strName;
}
};
int main(){
std::vector <CPerson> perr({
CPerson(),
CPerson("I.Ivanov", Sex::male, Titles::professor),
CPerson("A.Stoyanova", Sex::female, Titles::assistant),
CPerson("A.Dimitrova", Sex::female, Titles::assistant)
});
return 0;
}
Besides the missing types for Sex and Titles, the main problem was in the syntax of your vector initializer. I assume that you were trying to use an initializer list, but your syntax was all wrong. It looks like you were just copying variable declaration / initialization statements into it, but you need to create new instances of your CPerson class. These instances will then be copied into the vector.
CPerson p2("I.Ivanov", male, professor)
Declares and initializes a variable named p2 of class CPerson on the stack, but this syntax is not valid inside an initializer list, since you're not permitted to declare variables there. Instead use
CPerson("I.Ivanov", Sex::male, Titles::professor)
This creates an instance of CPerson, and this instance is then copied into the vector.
I am planning to use json c++ at https://github.com/nlohmann/json#examples . After reading its simple examples, I still have no idea how to use it with my own object? For example, I have a class
class Student
{
public:
Student(int id, string const& name)
: m_id(id), m_name(name)
{}
private:
int m_id;
string m_name;
};
How to use json to read and write (deserialize and serialize) a Student object?
this is another way to do the conversion from json to custom class, that actually fits the best practices defined in the official repo from nlohmann here
https://github.com/nlohmann/json#arbitrary-types-conversions
h:
#ifndef STUDENT_H
#define STUDENT_H
#include<string>
#include "json.hpp"
class Student
{
public:
Student();
Student(int id, const std::string &name);
int getId() const;
void setId(int newId);
std::string getName() const;
void setName(const std::string &newName);
private:
int m_id;
std::string m_name;
};
//json serialization
inline void to_json(nlohmann::json &j, const Student &s)
{
j["id"] = s.getId();
j["name"] = s.getName();
}
inline void from_json(const nlohmann::json &j, Student &s)
{
s.setId((j.at("id").get<int>()));
s.setName(j.at("name").get<std::string>());
}
#endif // STUDENT_H
cpp:
#include "Student.h"
#include<string>
Student::Student() : Student(0, "")
{
}
Student::Student(int id, const std::string &name) : m_id{id}, m_name{name}
{
}
int Student::getId() const
{
return this->m_id;
}
void Student::setId(int newId)
{
m_id = newId;
}
std::string Student::getName() const
{
return this->m_name;
}
void Student::setName(const std::string &newName)
{
this->m_name = newName;
}
example:
Student s{0, "x"};
nlohmann::json studentJson = s;
std::cout << "Student from object: " << s.getId() << std::endl;
std::cout << "Student from json: " << studentJson.at("id").get<int>() << std::endl;
//String
std::string jSt = studentJson.dump(); //{"id":0,"name":"x"}
Student s2 = studentJson;
Student s3 = nlohmann::json::parse(jSt);
This library doesnt seems to have any interaction with a class for serialization and deserialization.
But you can implement it yourself with a constructor and a getter.
using json = nlohmann::json;
class Student
{
public:
Student(int id, string const& name)
: m_id(id), m_name(name)
{}
Student(json data)
: m_id(data["id"]), m_name(data["name"])
{}
json getJson()
{
json student;
student["id"] = m_id;
student["name"] = m_name;
return student;
}
private:
int m_id;
string m_name;
};
I am trying to do a polymorphism in C++ language. My parent class is Person then there is a derived class called Student. Here is my Person.h and .cpp:
class Person
{
public:
Person(string name);
virtual void display() const;
string get_name() const;
void set_name(string name);
string get_birthDay() const;
void set_birthDay(string birthDay);
private:
string name;
string birthDay;
};
.cpp:
Person::Person(string name)
{
this->name = name;
}
string Person::get_name() const
{
return name;
}
void Person::set_name(string name)
{
this->name = name;
}
string Person::get_birthDay() const
{
return birthDay;
}
void Person::set_birthDay(string birthDay)
{
this->birthDay = birthDay;
}
void Person::display() const
{
cout << get_name() << " " << get_birthDay() << endl;
}
And this is my Student.h and .cpp:
class Student : public Person
{
public:
Student(string name, string major);
virtual void display() const;
string get_major() const;
void set_major(string major);
private:
string major;
};
.cpp:
Student::Student(string name, string major)
:Person(name)
{
this->major = major;
}
string Student::get_major() const
{
return major;
}
void Student::set_major(string major)
{
this->major = major;
}
void Student::display() const
{
cout << get_name() << " " << get_major() << endl;
}
All working perfectly until my main method. Here is my main method:
int main()
{
vector <Person*> person_list;
person_list.push_back(Student("Student","IT"));
person_list.push_back(Instructor("Instrructor", 2500));
for(int count=0; count< person_list.size(); count++)
{
cout << person_list[count]->display() << endl;
}
system("Pause");
return 0;
}
I got an error at the push_back and cout there. The error message for push_back to vector is: no instance of overloaded function matches the argument list. As for the cout, no operator matches the operands. I have no idea why. Anybody can help me fix it?
Thanks in advance.
Your person_list stores pointer but you pushed object instead:
To fix your issue:
person_list.push_back(new Student("Student","IT"));
//^^^^
person_list.push_back(new Instructor("Instrructor", 2500));
To store pointer in STL container, better use smart pointer:
#include <memory>
std::vector <std::unique_ptr<Person>> person_list;
You will need to push back a pointer to Student; i.e. use
person_list.push_back(new Student("Student","IT")); etc.
But, you will need to be very very careful with memory, since you will need to delete the memory you've allocated; the vector will not do this for you when it destructs.
Consider using a smart pointer instead.
cout << person_list[count]->display() << endl;
The display() function is of void return type. You cannot output that.
As for the push_back: like the others said, if you've got a vector of pointers, you need to push_back a pointer, not the object.
can you help me with composition in C++ please?
I have class User, who contains:
User.h
class User
{
public:
std::string getName();
void changeName(std::string nName);
std::string getGroup();
void changeGroup(std::string nGroup);
User(std::string nName, std::string nGroup);
~User(void);
private:
std::string name;
std::string group;
};
Now I define in class Honeypot:
Honeypot.h:
class Honeypot
{
public:
User us;
I have constructor:
Honeypot (std::string name, std::string ip, int numberOfInterfaces, std::string os);
in Honeypot.cpp:
Honeypot::Honeypot(std::string name, std::string ip, int numberOfInterfaces, std::string os):us(nName, nGroup){
this->name = name;
this->ip = ip;
this-> numberOfInterfaces = numberOfInterfaces;
this->os = os;
}
But this syntax is not correct. Errors are:
IntelliSense: expected a ')', 'nGroup' : undeclared identifier and more on line :us(nName, nGroup){...
Thank you for help.
nName and nGroup need to be parameters of the Honeypot constructor; as the compiler indicates, they're undeclared.
Honeypot::Honeypot(std::string name, std::string ip,
int numberOfInterfaces, std::string os,
std::string userName, std::string userGroup)
: us(userName, userGroup)
{
this->name = name;
this->ip = ip;
this->numberOfInterfaces = numberOfInterfaces;
this->os = os;
}