Define dynamic arrays in class inheritance - c++

I am trying to initialize 2 dynamic arrays which class student will have an array containing all the courses registered and class course will have an array containing all the students registered to the class. I defined class Course and Student like this:
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
class Course;
class Student {
std::string name; // person’s name
int id; // person’s age
Course* courses;
int course_register; // number of organization registered to
public:
Student();
Student(const Student& s) {
name = s.getName();
id = s.getAge();
course_register = s.getorg_register();
}
Student(std::string n, int i) {
id = i;
name = n;
}
int getAge() const { return id; }
string getName() const { return name; }
int getorg_register() const { return course_register; }
};
class Course {
std::string name; // name of the org
Student* students; // list of members
int size; // actual size of the org
int dim; // max size of the org
public:
Course()
{
dim = 100;
students = new Student[dim];
};
Course(const Course& course)
{
name = course.getName();
dim = course.getDim();
size = course.getSize();
students = new Student[dim];
for (int i = 0; i < size; i++) {
students[i] = course.getStudent(i);
}
}
~Course()
{
delete[] students;
}
Student getStudent(int i) {return students[i];}
Student* getStudents() {return students;}
int getSize(){return size;}
int getDim() {return dim;}
string getName() {return name;}
};
Student::Student() {
courses = new Course[5];
}
When I try to compile, I get an exception unhandled at runtime for constructor Student::Student(). Can someone explain to me why I get a runtime error? And how would you change it to make it work?

A Student should contain a list that refers to the Courses it is enrolled in, it should not create the Courses themselves.
A Course should contain a list that refers to the Students enrolled in it, it should not create the Students themselves.
Does that make sense? In this case, refers means "use a pointer". For instance, Student could have a std::vector<Course*>, and Course could have a std::vector<Student*>. Then you can have a method that enrolls a Student into a Course, where a pointer to the Student is added to the Course's list, and a pointer to the Course is added to the Student's list, eg:
Student.h
#ifndef StudentH
#define StudentH
#include <string>
#include <vector>
class Course;
class Student {
std::string name;
int id;
std::vector<Course*> courses;
void addCourse(Course *c);
void removeCourse(Course *c);
friend class Course;
public:
Student(std::string n, int i);
Student(const Student& s);
Student(Student&& s);
~Student();
Student& operator=(Student rhs);
int getId() const;
string getName() const;
std::vector<Course*> getCourses() const;
void enroll(Course &c);
void drop(Course &c);
};
#endif
Student.cpp
#include "Student.h"
#include "Course.h"
Student::Student(std::string n, int i) {
name = n;
id = i;
}
Student::Student(const Student& s) {
name = s.name;
id = s.id;
for (Course *c : s.courses) {
c->enroll(*this);
}
}
Student::Student(Student&& s) {
name = std::move(s.name);
id = s.id; s.id = 0;
courses = std::move(s.courses);
for (Course *c : courses) {
c->removeStudent(&s);
c->addStudent(this);
}
}
Student::~Student() {
for(Course *c : courses) {
c->removeStudent(this);
}
}
Student& Student::operator=(Student rhs) {
Student temp(std::move(rhs));
for (Course *c : courses) {
c->removeStudent(this);
}
name = std::move(temp.name);
id = temp.id; temp.id = 0;
courses = std::move(temp.courses);
for (Course *c : courses) {
c->removeStudent(&temp);
c->addStudent(this);
}
return *this;
}
void Student::addCourse(Course *c) {
if (std::find(courses.begin(), courses.end(), c) == courses.end()) {
courses.push_back(c);
}
}
void Student::removeCourse(Course *c) {
auto iter = std::find(courses.begin(), courses.end(), c);
if (iter != courses.end())
courses.erase(iter);
}
}
int Student::getId() const {
return id;
}
string Student::getName() const {
return name;
}
std::vector<Course*> Student::getCourses() const {
return courses;
}
void Student::enroll(Course &c) {
c.enroll(*this);
}
void Student::drop(Course &c) {
c.drop(*this);
}
Course.h
#ifndef CourseH
#define CourseH
#include <string>
#include <vector>
class Student;
class Course {
std::string name;
std::vector<Student*> students;
void addStudent(Student *s);
void removeStudent(Student *s);
friend class Student;
public:
Course(std::string n);
Course(const Course& c);
Course(Course&& c);
~Course();
Course& operator=(Course rhs);
string getName() const;
std::vector<Student*> getStudents() const;
void enroll(Student &s);
void drop(Student &s);
};
#endif
Course.cpp
#include "Course.h"
#include "Student.h"
Course::Course(std::string n) {
name = n;
}
Course::Course(const Course& c) {
name = c.name;
for (Student *s : c.students) {
enroll(*s);
}
}
Course::Course(Course&& c) {
name = std::move(c.name);
students = std::move(c.students);
for (Student *s : students) {
s->removeCourse(&c);
s->addCourse(this);
}
}
Course::~Course()
{
for(Student *s : students) {
s->removeCourse(this);
}
}
Course& Course::operator=(Course rhs)
{
Course temp(std::move(rhs));
for (Student *s : students) {
s->removeCourse(this);
}
name = std::move(temp.name);
students = std::move(temp.students);
for (Student *s : students) {
s->removeCourse(&temp);
s->addCourse(this);
}
return *this;
}
void Course::addStudent(Student *s) {
if (std::find(students.begin(), students.end(), s) == students.end()) {
students.push_back(s);
}
}
void Course::removeStudent(Student *s) {
auto iter = std::find(students.begin(), students.end(), s);
if (iter != students.end())
students.erase(iter);
}
}
string Course::getName() const {
return name;
}
std::vector<Student*> Course::getStudents() const {
return students;
}
void Course::enroll(Student &s) {
addStudent(&s);
s.addCourse(this);
}
void Course::drop(Student &s) {
removeStudent(&s);
s.removeCourse(this);
}
Main.cpp
#include "Student.h"
#include "Course.h"
int main()
{
Course c("Math");
Student p("Joe", 12345);
p.enroll(c);
return 0;
}

You have infinite recursion. The Course constructor calls the Student constructor. The Student constructor calls the Course constructor. This continues until you've used up all the stack space.
You'll want to rethink your design of your two classes.

Related

Class does not persist vector of objects after addition

My code is as shown below. The problem is inside the int main() function, r.printItems() is not printing anything. What am I missing here?
main.cpp
#include <bits/stdc++.h>
#include "Customer.h"
#include "MenuCreator.h"
#include "FoodItem.h"
MenuCreator m1;
void createCustomer() {
Customer c1("mrg", "m#gmail.com", "9654357", "+91");
}
void createRestaurantItem(Restaurant &rest) {
rest.addItems(FoodItem("t1"));
rest.addItems(FoodItem("D1"));
}
void createMenu() {
m1.createMenu("sg");
Category c1;
c1.setName("Non-veg");
m1.addCategory(c1);
Restaurant r1;
r1.setName("ABC");
r1.setDescription("Test Restaurant");
createRestaurantItem(r1);
c1.addRestaurants(r1);
}
vector<Restaurant> getRestaurantsForCategory(string category) {
return m1.getRestaurantsForCategories(category);
}
int main() {
createCustomer();
createMenu();
for (auto r: getRestaurantsForCategory("Non-veg")) {
r.printItems();
}
return 0;
}
MenuCreator.h
#include <bits/stdc++.h>
#include "Menu.h"
using namespace std;
class MenuCreator {
public:
void createMenu(string name) {
Menu m1;
m1.setName(name);
menu = m1;
}
void addCategory(const Category &categ) {
categories.push_back(categ);
}
const Menu &getMenu() const {
return menu;
}
const vector<Category> &getCategories() const {
return categories;
}
void addRestaurantForCategory(string name, const Restaurant restaurant) {
for(auto categ: categories) {
if (categ.getName() == name) {
categ.addRestaurants(restaurant);
}
}
}
const vector<Restaurant> &getRestaurantsForCategories(string category) {
for(auto categ: categories) {
if(categ.getName() == category) return categ.getRestaurants();
}
}
private:
Menu menu;
vector<Category> categories;
};
Menu.h
#include<bits/stdc++.h>
#include "Category.h"
using namespace std;
class Menu {
public:
const string &getName() const {
return name;
}
void setName(const string &name) {
Menu::name = name;
}
private:
string name;
string description;
vector<Category> categories;
};
Category.h
using namespace std;
class Category {
public:
const string &getName() const {
return name;
}
void setName(const string &name) {
Category::name = name;
}
const string &getDescription() const {
return description;
}
void setDescription(const string &description) {
Category::description = description;
}
const vector<Restaurant> &getRestaurants() const {
return restaurants;
}
void setRestaurants(const vector<Restaurant> &restaurants) {
Category::restaurants = restaurants;
}
void addRestaurants(const Restaurant &rt) {
Category::restaurants.push_back(rt);
}
private:
string name;
string description;
vector<Restaurant> restaurants;
};
FoodItem.h
#include <bits/stdc++.h>
#include <vector>
#include "FoodItem.h"
using namespace std;
class Restaurant {
public:
Restaurant() {
this->id = gen_random(12);
}
virtual ~Restaurant() {
}
const string &getName() const {
return name;
}
void setName(const string &name) {
Restaurant::name = name;
}
const string &getDescription() const {
return description;
}
void setDescription(const string &description) {
Restaurant::description = description;
}
double getLat() const {
return lat;
}
void setLat(double lat) {
Restaurant::lat = lat;
}
double getLang() const {
return lang;
}
void setLang(double lang) {
Restaurant::lang = lang;
}
const string &getImageUrl() const {
return imageUrl;
}
void setImageUrl(const string &imageUrl) {
Restaurant::imageUrl = imageUrl;
}
const string &getVideoUrl() const {
return videoUrl;
}
void setVideoUrl(const string &videoUrl) {
Restaurant::videoUrl = videoUrl;
}
const vector<FoodItem> &getItems() const {
return items;
}
void setItems(const vector<FoodItem> &items) {
Restaurant::items = items;
}
void addItems(const FoodItem &item) {
this->items.push_back(item);
}
string gen_random(const int len) {
string tmp_s;
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
srand( (unsigned) time(NULL) * getpid());
tmp_s.reserve(len);
for (int i = 0; i < len; ++i)
tmp_s += alphanum[rand() % (sizeof(alphanum) - 1)];
return tmp_s;
}
const string &getId() const {
return id;
}
void printItems() {
for(auto it: items) {
cout<<"item: "<<it.getName()<<endl;
}
}
private:
string id;
string name;
string description;
double lat;
double lang;
string imageUrl;
string videoUrl;
string createdAt;
string updatedAt;
vector<FoodItem> items;
};
Restaurant.h
#include <bits/stdc++.h>
#include <vector>
#include "FoodItem.h"
using namespace std;
class Restaurant {
public:
Restaurant() {
this->id = gen_random(12);
}
virtual ~Restaurant() {
}
const string &getName() const {
return name;
}
void setName(const string &name) {
Restaurant::name = name;
}
const string &getDescription() const {
return description;
}
void setDescription(const string &description) {
Restaurant::description = description;
}
double getLat() const {
return lat;
}
void setLat(double lat) {
Restaurant::lat = lat;
}
double getLang() const {
return lang;
}
void setLang(double lang) {
Restaurant::lang = lang;
}
const string &getImageUrl() const {
return imageUrl;
}
void setImageUrl(const string &imageUrl) {
Restaurant::imageUrl = imageUrl;
}
const string &getVideoUrl() const {
return videoUrl;
}
void setVideoUrl(const string &videoUrl) {
Restaurant::videoUrl = videoUrl;
}
const vector<FoodItem> &getItems() const {
return items;
}
void setItems(const vector<FoodItem> &items) {
Restaurant::items = items;
}
void addItems(const FoodItem &item) {
this->items.push_back(item);
}
string gen_random(const int len) {
string tmp_s;
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
srand( (unsigned) time(NULL) * getpid());
tmp_s.reserve(len);
for (int i = 0; i < len; ++i)
tmp_s += alphanum[rand() % (sizeof(alphanum) - 1)];
return tmp_s;
}
const string &getId() const {
return id;
}
void printItems() {
for(auto it: items) {
cout<<"item: "<<it.getName()<<endl;
}
}
private:
string id;
string name;
string description;
double lat;
double lang;
string imageUrl;
string videoUrl;
string createdAt;
string updatedAt;
vector<FoodItem> items;
};
When createMenu() in main.cpp is setting up the menu, it creates a local Category object named c1 and adds it to the menu, which makes a copy of c1 when pushingnit into the MenuCreator::categories vector. No Restaurant objects had been added to c1 yet when that copy is created. So when a Restaurant is then added to c1 afterwards, the copy is not updated. That is why there are no Restaurant objects in the menu when MenuCreator::getRestaurantsForCategory() tries to return them.
Change createMenu() to fully initialize c1 before adding it to the menu, eg:
void createMenu() {
m1.createMenu("sg");
Category c1;
c1.setName("Non-veg");
Restaurant r1;
r1.setName("ABC");
r1.setDescription("Test Restaurant");
createRestaurantItem(r1);
c1.addRestaurants(r1);
m1.addCategory(c1); // <-- move down here
}
Also, on a side note, the return value of MenuCreator::getRestaurantsForCategories() is undefined if the specified category is not found. Since the return value is a reference to a vector, it needs to either return a static vector that is empty, or else throw an exception.

How to sort a vector of pointers to different instances of a class with multiple criteria?

I need to sort a vector of pointers with this test data.
main.cpp
#include "cart.h"
int main()
{
Cart cart;
cart.addItem("Desktop", 125.34f);
cart.addItem("Iphone", 46.274f);
cart.addItem("Pen", 118.99f);
cart.addItem("Ruler", 41.34f);
cart.addItem("Printer", 2.99f);
cart.printSortedItems();
cart.destroy();
}
item.h
#include <string>
#include <tuple>
class Item
{
private:
Item(const std::string& name, const ItemType& itemType, const float& price);
~Item();
std::string m_name;
float m_price;
public:
static Item *getInstance(const std::string& name, const float& price);
bool operator>(const Item& item2) const;
void print() const;
};
item.cpp
#include "item.h"
#include <iostream>
Item::Item(const std::string& name, const float& price)
{
m_name = name;
m_price = price;
}
Item::~Item()
{
}
Item *Item::getInstance(const std::string& name, const float& price)
{
return new Item(name, price);
}
bool Item::operator>(const Item & item2) const
{
if (m_name > item2.m_name) {
return true;
}
if (m_name == item2.m_name && m_price > item2.m_price) {
return true;
}
return false;
}
void Item::print() const
{
std::cout << "Item name: " << m_name << " Item price: "<< m_price << std::endl;
}
cart.h
#include <vector>
class Cart
{
public:
Cart();
~Cart();
void addItem(const std::string& name, const float& price);
void printSortedItems();
void sortItems();
void destroy();
private:
std::vector<Item*> m_itemList = {};
};
cart.cpp
#include "cart.h"
#include <iostream>
#include <algorithm>
Cart::Cart(){}
Cart::~Cart(){}
void Cart::addItem(const std::string& name, const float& price)
{
Item *newItem = Item::getInstance(name, itemType, price);
m_itemList.push_back(newItem);
}
void Cart::sortItems()
{
for (size_t i = 0; i < m_itemList.size()-1; i++)
{
for (size_t j = i + 1; j < m_itemList.size(); j++)
{
if (m_itemList[i] > m_itemList[j])
{
std::swap(m_itemList[i], m_itemList[j]);
}
}
}
}
void Cart::printSortedItems()
{
sortItems();
std::cout << "Items" << std::endl;
for (size_t i = 0; i < m_itemList.size(); i++)
{
m_itemList[i]->print();
}
std::cout << std::endl;
}
void Cart::destroy()
{
for (size_t i = 0; i < m_itemList.size(); i++)
{
delete m_itemList[i];
m_itemList[i] = nullptr;
}
}
In function Cart::sortItems(), I compare m_itemList[i] and m_itemList[j], these are both pointers to instance of Item. Theoretically, if I set a break point in bool Item::operator>(const Item & item2) const, it should be hit. But in this case, the break point is not hit, and therefore, the result after sorting is wrong. Could you guys tell me where I am wrong?

Passing c-strings to class function (assigning it to class member)

I have a class called Person:
class Person {
private:
char name[50];
unsigned int number;
public:
void set_data(const char *newname, unsigned int number) {
*name= *newname; //THE MAIN PROBLEM I WANT TO SOLVE
this->number = number;
}
char* get_name() {
return this->name;
}
unsigned int get_number() {
return this->number;
}
};
I have arrays:
const char *names[] = {"Mark", "Pavel", "Bill", "Jasur", "Jeff"};
int phones[] = { 1234567890, 9876543210, 123321456654, 1998946848479, 1234554321 };
I'm using for loop to set Person members:
Person p;
for (int i = 0; i < 5; i++) {
p.set_data(names[i], phones[i]);
cout << p.get_name() << endl;
}
When I run this, I'm getting wrong output.
Using * the way you are, you are only copying the 1st char into name. You are also not null-terminating name either, which is required by the overloaded operator<< that takes a char* as input.
To copy the entire string, you need to use std::strcpy() (or better, std::strncpy()) instead, eg:
#include <cstring>
void set_data(const char *newname, unsigned int newnumber) {
//std::strcpy(name, newname);
std::strncpy(name, newname, 49);
name[49] = '\0';
number = newnumber;
}
However, since this is C++ and not C, you really should be using std::string instead:
#include <string>
class Person {
private:
std::string name;
unsigned int number;
public:
void set_data(const std::string &newname, unsigned int newnumber) {
name = newname;
number = newnumber;
}
std::string get_name() const {
return name;
}
/* or:
const std::string& get_name() const {
return name;
}
*/
unsigned int get_number() const {
return number;
}
};

0xC0000005: Access violation writing location 0xCCCCCCCC caused by trying to make safe empty chars

I've been pulling my hair out over a certain error that seems to be plaguing my program. I've attempted to search online for cases similar to mine but I can't seem to find a way to apply the other solutions to this problem. My issue is as follows: When I initially open the program it immediately stops responding and crashes. Debugging led me to find the error in question is "0xC0000005: Access violation writing location 0xCCCCCCCC". It seems to be tied to me assigning two attributes (sku_ and name_ ) as '\0'. If I change these values to anything else such as "" or even "\0" the program runs in visual studio, but will fail to compile elsewhere. Could someone help me understand where I am going wrong?
Product.h
#ifndef SICT_Product_H__
#define SICT_Product_H__
#include "general.h"
#include "Streamable.h"
#include <cstring>
namespace sict {
class Product : public Streamable {
char sku_ [MAX_SKU_LEN + 1];
char* name_;
double price_;
bool taxed_;
int quantity_;
int qtyNeeded_;
public:
//Constructors
Product();
Product(const char* sku, const char* name1, bool taxed = true, double price = 0, int qtyNeeded =0);
Product(Product& g);
~Product();
//Putter Functions
void sku(const char* sku) { strcpy(sku_,sku); };
void price(double price) {price_ = price;};
void name(const char* name);
void taxed(bool taxed) { taxed_ = taxed; };
void quantity(int quantity) { quantity_ = quantity; };
void qtyNeeded(int qtyNeeded) { qtyNeeded_ = qtyNeeded; };
//Getter functions
const char* sku() const { return sku_; };
double price() const { return price_; };
const char* name() const { return name_; };
bool taxed() const { return taxed_; };
int quantity() const { return quantity_; };
int qtyNeeded() const { return qtyNeeded_; };
double cost() const;
bool isEmpty() const;
Product& operator=(const Product& );
bool operator==(const char* );
int operator+=(int );
int operator-=(int );
};
double operator+=(double& , const Product& );
std::ostream& operator<<(std::ostream& os, const Product& );
std::istream& operator>>(std::istream& is, Product& );
}
#endif
Product.cpp
#include <iostream>
#include <cstring>
#include "Product.h"
namespace sict {
Product::Product() {
sku_[0] = '\0';
name_[0] = '\0';
price_ = 0;
quantity_ = 0;
qtyNeeded_ = 0;
}
Product::Product(const char* sku, const char* name1, bool taxed1, double price1, int qtyNeeded1) {
strncpy(sku_, sku, MAX_SKU_LEN);
name(name1);
quantity_ = 0;
taxed(taxed1);
price(price1);
qtyNeeded(qtyNeeded1);
}
double Product::cost() const {
if (taxed_ == true) {
return (price_ * TAX) + price_;
}
else
return price_;
}
bool Product::isEmpty() const{
if (sku_ == nullptr && name_ == nullptr && quantity_ == 0 && price_ == 0 && qtyNeeded_ == 0) {
return true;
}
else
return false;
}
Product::Product(Product& ex) {
sku(ex.sku_);
price(ex.price_);
name(ex.name_);
taxed(ex.taxed_);
quantity(ex.quantity_);
qtyNeeded(ex.qtyNeeded_);
}
Product& Product::operator=(const Product& g) {
sku(g.sku_);
price(g.price_);
name(g.name_);
taxed(g.taxed_);
quantity(g.quantity_);
qtyNeeded(g.qtyNeeded_);
return *this;
}
Product::~Product() {
delete [] name_;
}
void Product::name(const char* name) {
name_ = new char [strlen(name) + 1];
strcpy(name_, name);
}
bool Product::operator==(const char* right) {
if (sku_ == right) {
return true;
}
else
return false;
}
int Product::operator+=(int g) {
quantity_ = quantity_ + g;
return quantity_;
}
int Product::operator-=(int g) {
quantity_ = quantity_ - g;
return quantity_;
}
double operator+=(double& p, const Product& right) {
p = p + (right.cost() * right.quantity());
return p;
}
std::ostream& operator<<(std::ostream& os, const Product& g) {
return g.write(os, true);
}
std::istream& operator>>(std::istream& is, Product& g) {
return g.read(is);
}
}
The General.h file referenced in the header is just a list of constant values such as the "TAX" and "MAX_SKU_LEN" values.
The Streamable header contains pure virtual functions. I will list it here in case it is needed.
Streamable.h
#ifndef SICT__Streamable_H_
#define SICT__Streamable_H_
#include <iostream>
#include <fstream>
#include "Product.h"
namespace sict {
class Streamable {
public:
virtual std::fstream& store(std::fstream& file, bool addNewLine = true)const = 0;
virtual std::fstream& load(std::fstream& file) = 0;
virtual std::ostream& write(std::ostream& os, bool linear)const = 0;
virtual std::istream& read(std::istream& is) = 0;
};
}
#endif
Thank you very much in advance.
Product::Product() {
sku_[0] = '\0';
name_[0] = '\0'; // <---- writing via unitialized pointer
price_ = 0;
quantity_ = 0;
qtyNeeded_ = 0;
}
There's one possible source of your problems. You have defined a char pointer (a dynamic array or a C-string, that is) name_ in your class but you never allocate any memory for it in your constructor, before attempting to record a value via the pointer. Naturally, you get a write access violation.
Before assigning the value to char at index [0] you need to first allocate space for at least one element in your string, e.g. by doing name_ = new char [1]. Alternatively, you may choose to initialize the pointer itself to NULL (or nullptr) and use that to indicate that name_ has not yet been set.

cannot swap objects in an array in C++

i am new to C++ and stuck in the swap stuff
the code below is a program of sort employee names in alphbetical order and print out the orginal one and sorted one ,but the
swap method doesn't work
the two output of printEmployees is excatly the same, can anyone help me? thx
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>
using namespace std;
class employee
{
/* Employee class to contain employee data
*/
private:
string surname;
double hourlyRate;
int empNumber;
public:
employee() {
hourlyRate = -1;
empNumber = -1;
surname = "";
}
employee(const employee &other) :
surname(other.surname),
hourlyRate(other.hourlyRate),
empNumber(other.empNumber){}
void setEmployee(const string &name, double rate,int num);
string getSurname() const;
void printEmployee() const;
employee& operator = (const employee &other)
{employee temp(other);
return *this;}};
void employee::setEmployee(const string &name, double rate, int num) {
surname = name;
hourlyRate = rate;
empNumber = num;
}
string employee::getSurname() const { return surname; }
void employee::printEmployee() const {
cout << fixed;
cout << setw(20) << surname << setw(4) << empNumber << " " << hourlyRate << "\n";
}
void printEmployees(employee employees[], int number)
{
int i;
for (i=0; i<number; i++) { employees[i].printEmployee(); }
cout << "\n";
}
void swap(employee employees[], int a, int b)
{
employee temp(employees[a]);
employees[a] = employees[b];
employees[b] = temp;
}
void sortEmployees(employee employees[], int number)
{
/* use selection sort to order employees,
in employee
name order
*/
int inner, outer, max;
for (outer=number-1; outer>0; outer--)
{
// run though array number of times
max = 0;
for (inner=1;
inner<=outer; inner++)
{
// find alphabeticaly largest surname in section of array
if (employees
[inner].getSurname() < employees[max].getSurname())
max = inner;
}
if (max != outer)
{
//
swap largest with last element looked at in array
swap(employees, max, outer);
}
}
}
int main()
{
employee employees[5];
employees[0].setEmployee("Stone", 35.75, 053);
employees[1].setEmployee
("Rubble", 12, 163);
employees[2].setEmployee("Flintstone", 15.75, 97);
employees[3].setEmployee("Pebble", 10.25, 104);
employees[4].setEmployee("Rockwall", 22.75, 15);
printEmployees(employees, 5);
sortEmployees(employees,5);
printEmployees(employees, 5);
return 0;
}
This code is broken:
employee& operator = (const employee &other)
{employee temp(other);
return *this;}
It should be something like:
employee& operator= (const employee &other)
{
surname = other.surname;
hourlyRate = other.hourlyRate;
empNumber = other.empNumber;
return *this;
}
As told by others, fixing your assignment operator will solve the problem.
I see that you tried to implement operator= in terms of copy constructor but missed to do a swap. You can try the below approach if you want to avoid code duplication in your copy constructor and assignment operator.
employee& operator=(const employee& other)
{
employee temp(other);
swap(temp);
return *this;
}
void swap(employee& other)
{
std::swap(surname, other.surname);
std::swap(hourlyRate, other.hourlyRate);
std::swap(empNumber, other.empNumber);
}