How to write constructor with composition in C++? - c++

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;
}

Related

How to overload operator += in cpp?

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.

Need help understanding the syntax of C++ Classes

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...

Initialize a STL vector with object of type CPerson (class) in C++?

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.

Copy string in C++

I would like to convert this constructor's argument from const char* to std::string, but I don't know how to copy the new name to name properly.
Player::Player(const char* name) :
level(1),life(1),strength(1),place(0){
char* new_player_name = new char[strlen(name) + 1];
strcpy(new_player_name, name);
this->player_name = new_player_name;
}
Player::Player(string name) :
level(1),life(1),strength(1),place(0){
string new_player_name(' ',name.length() + 1); //#1
// I didn't know how to proceed
}
The classes data-members:
class Player {
char* player_name;
int level;
int life;
int strength;
int place;
};
Consider making player_name a std::string.
Then your constructor could start
Player::Player(const char* name) : player_name(name)
{
and you don't need to fiddle about with all those dynamically allocated char arrays.
You could change the type of name to a const std::string& too:
Player::Player(const std::string& name) : player_name(name)
{

How to use json c++ with my own object?

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;
};