-1

my code has 3 classes user, book and userList the user list is a class that creates an array of users. I am a beginner so any help would be greatly appreciated. I will list the file names and their code after user.h

#pragma once
#ifndef USER_H
#define USER_H
#include<cstring>
#include<iostream>
#pragma warning( disable : 4716 )
using namespace std;
class user
{
private:
    string name;
    int age;
    int id;
    string password;
    string email;

public:
    static int count;
    void setName(string Name);
    string getName();
    void setPassword(string Password);
    string getPassword();
    void setEmail(string Email);
    string getEmail();
    void setAge(int Age);
    int getAge();
    void setId();
    int getId();
    user();
    user(string Name, int Age, string Email, string Password);
    user(const user& u);
    bool operator ==(const user& u);
    friend ostream& operator<<(ostream& output, const user& u);
    friend istream& operator>>(istream& input, user& u);
};
#endif

user.cpp

#include "user.h"

void user::setName(string Name)
{
    name = Name;
}

string user::getName()
{
    return name;
}

void user::setPassword(string Password)
{
    password = Password;
}

string user::getPassword()
{
    return password;
}

void user::setEmail(string Email)
{
    Email = email;
}

string user::getEmail()
{
    return email;
}

void user::setAge(int Age)
{
    age = Age;
}

int user::getAge()
{
    return age;
}

void user::setId()
{
    count++;
    id = count;
}

int user::getId()
{
    return id;
}

user::user()
{
    age = 0;
    name = password = email = "";
}

user::user(string Name, int Age, string Email, string Password)
{
    name = Name;
    password = Password;
    email = Email;
    age = Age;
}

user::user(const user& u)
{
    name = u.name;
    age = u.age;
    email = u.email;
    password = u.password;
    id = u.id;
}

bool user::operator==(const user& u)
{
    bool status;
    if (name == u.name && age == u.age && email == u.email && id == u.id)
    {
        status = true;
    }
    else
    {
        status = false;
    }
}

ostream& operator<<(ostream& output, const user& u)
{
    output << endl << "User name :" << u.name << endl << "User id :" << u.id << endl << "User age :" << u.age << endl << "User email :" << u.email << endl << "User password :" << u.password << endl;
}

istream& operator>>(istream& input, user& u)
{

    input >> u.name >> u.age >> u.email >> u.password;
}

Book.h

#pragma once
#ifndef BOOK_H
#define BOOK_H
#include<cstring>
#include<iostream>
#include "user.h"
#pragma warning( disable : 4716 )
using namespace std;
class Book
{
private:
    string title;
    string isbn;
    int id;
    string category;
    double averageRating;
    user author;
public:
    static int count;
    void setTitle(string Title);
    string getTitle();
    void setISBN(string ISBN);
    string getISBN();
    void setId();
    int getId();
    void setCategory(string Category);
    string getCategory();
    void setRating(double Rating);
    double getRating();
    void setAuthor(user User);
    user getAuthor();
    Book();
    Book(const Book& b);
    bool operator==(const Book& b);
    friend ostream& operator<<(ostream& output, const Book& b);
    friend istream& operator>>(istream& input, Book& b);

};
#endif

Book.cpp

#include "Book.h"

void Book::setTitle(string Title)
{
    title = Title;
}

string Book::getTitle()
{
    return title;
}

void Book::setISBN(string ISBN)
{
    isbn = ISBN;
}

string Book::getISBN()
{
    return isbn;
}

void Book::setId()
{
    count++;
    id = count;
}

int Book::getId()
{
    return id;
}

void Book::setCategory(string Category)
{
    category = Category;
}

string Book::getCategory()
{
    return category;
}

void Book::setRating(double Rating)
{
    averageRating = Rating;
}

double Book::getRating()
{
    return averageRating;
}

void Book::setAuthor(user User)
{
    author = User;
}

user Book::getAuthor()
{
    return author;
}

Book::Book()
{
    title = isbn = category = "";
    averageRating = 0;
}

Book::Book(const Book& b)
{
    title = b.title;
    isbn = b.isbn;
    category = b.category;
    author = b.author;
    id = b.id;
    averageRating = b.averageRating;
}

bool Book::operator==(const Book& b)
{
    bool status;
    if (title == b.title && isbn == b.isbn && category == b.category && id == b.id && author == b.author)
    {
        status = true;
    }
    else
    {
        status = false;
    }
}

ostream& operator<<(ostream& output, const Book& b)
{
    output << endl << "Book title :" << b.title << endl << "Book ISBN :" << b.isbn << endl << "Book ID :" << b.id << endl << "Book category :" << b.category << endl << "Average rating :" << b.averageRating << endl;
}

istream& operator>>(istream& input, Book& b)
{
    input >> b.title >> b.isbn >> b.category;
}

UserList.h

#pragma once
#include<cstring>
#include<iostream>
#include "user.h"
using namespace std;
class UserList
{
private:
    user* users;
    int capacity;
    int usersCount;
public:
    UserList(int Capacity);
    void addUser(user user);
    user& searchUserID(int id);
    user& searchUserName(string name);
    void deleteUser(int id);
    friend ostream& operator<<(ostream& output, const UserList& userList);
    ~UserList();
};

UserList.cpp

#include "UserList.h"

UserList::UserList(int Capacity)
{
    usersCount = 0;
    capacity = Capacity;
    user udef;
    users = new user[capacity];
    for (int i = 0; i < capacity; i++)
    {
        users[i] = udef;
    }
}

void UserList::addUser(user newuser)
{
    users[usersCount] = newuser;
    usersCount++;
}
user& UserList::searchUserName(string name)
{
    cout << "Enter the user's name" << endl;
    cin >> name;
    for (int i = 0; i < usersCount; i++)
    {
        if (name == users[i].getName())
        {
            cout << users[i];
        }
        else cout << "USER NOT FOUND !!!!" << endl;
    }
}
user& UserList::searchUserID(int id)
{
    cout << "Enter the user's ID" << endl;
    cin >> id;
    for (int i = 0; i < usersCount; i++)
    {
        if (id == users[i].getId())
        {
            cout << users[i];
        }
        else cout << "USER NOT FOUND !!!!" << endl;
    }
}



void UserList::deleteUser(int id)
{
    cout << "Enter the user's ID" << endl;
    cin >> id;
    int i;
    for (i = 0; i < usersCount; i++)
    {
        if (id == users[i].getId())
        {
            break;
        }
    }
    for (i; i < usersCount; i++)
    {
        users[i] = users[i + 1];
    }
    usersCount--;
}
ostream& operator<<(ostream& output, const UserList& userList)
{
    for (int i = 0; i < userList.usersCount; i++)
    {
        output << "---- USER " << i + 1 << "----" << userList.users[i];
    }
}
UserList::~UserList()
{
    delete users;
}

main.cpp

#include<cstring>
#include<iostream>
#include "user.h"
#include "Book.h"
#include "UserList.h"
#pragma warning( disable : 4716 )
using namespace std;
int user::count = 0;
int Book::count = 0;
int main()
{
    int size;
    cout << "enter the size of the list" << endl;
    cin >> size;
    UserList ul1(size);
    cout << ul1 << endl;
    return 0;
}
  • `user* users;` --> `std::vector users;` -- There is no need to make this harder than it needs to be. Once that change is made, a lot of that code you have written can be gotten rid of, and it won't be surprising if your error(s) magically go away. – PaulMcKenzie Dec 22 '20 at 15:59
  • thanks but this is an assignment and we are obliged to use arrays – Mohamed Hesham Dec 22 '20 at 16:01
  • 1
    Does your assignment also require you to write totally unnecessary code, like those user-defined copy constructor, assignment operator, and destructor for the `Book` and `User` classes? As a matter of fact, it is the `UserList` class that requires those functions, but are missing. The `UserList` class violates the [rule of 3](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – PaulMcKenzie Dec 22 '20 at 16:04
  • Example: `int main() { UserList u1; UserList u2 = u1; }` That simple two line program has a double free error. – PaulMcKenzie Dec 22 '20 at 16:09
  • It was a two part assignment the first one was thee book and user classes the second one is implementing the user list class but most of the functions are still unused because the main that I sent is only a test – Mohamed Hesham Dec 22 '20 at 16:10
  • 2
    What I'm saying is that the `Book` and `User` class do not need any user-defined copy constructor written. If you look at the members, they are all safely copyable, thus the compiler's version of the copy constructor is preferable to anything hand-written. The compiler's version works, is not faulty, efficient, etc. Also, did you heed your compiler warnings about returning no value from functions that require a return value? `user& UserList::searchUserName(string name)` -- What do you return in this function? – PaulMcKenzie Dec 22 '20 at 16:11
  • I get what you are saying but it was required in the assignment. – Mohamed Hesham Dec 22 '20 at 16:14
  • i tried to return the values but could not but did not know if i can change the return value of said function – Mohamed Hesham Dec 22 '20 at 16:19
  • 1
    Well, this is the danger of writing and running code that invokes undefined behavior. Until you complete those functions, your code can't run correctly (it may right now, due to `main` being a toy program, but a simple change in `main` reveals all the major faults in your code). – PaulMcKenzie Dec 22 '20 at 16:20
  • Woe betide the institute which teaches C++ to its under-grads. I want to meet your instructor. – Tanveer Badar Dec 22 '20 at 17:00
  • @MohamedHesham Did you try running it in a debugger? Also, if you use `clang++` or `g++` to compile it, add these compiler options: `-Wall -Wextra -Werror -pedantic -pedantic-errors`. – Ted Lyngmo Dec 22 '20 at 17:25
  • Unrelated: Why are you defining the `static` variables for `user` and `Book` in `main.cpp`? Move that to `user.cpp` and `Book.cpp` resp. – Ted Lyngmo Dec 22 '20 at 17:27

1 Answers1

1

There are several issues with your code.

In the UserList destructor:

delete users;

This is the wrong form of delete. This should be:

delete [] users;

Since new[] was used to allocate the array, delete [] must be used.


The other major issue that has to be fixed is this one in UserList:

ostream& operator<<(ostream& output, const UserList& userList)

You need to return output;, but your code fails to do so. Not returning a value from a function that has a return value invokes undefined behavior.

As a matter of fact, several of your functions require you to return values, yet you failed to do so. Thus any calls to those functions will result in undefined behavior.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • thank you so much for your modifications i did them but I still get the same error – Mohamed Hesham Dec 22 '20 at 16:48
  • Regardless if you get the same error, those fixes are required for your program to work. Also, maybe the original error was caused by one of the ones mentioned in the answer, and now your error is caused by something else in the program. – PaulMcKenzie Dec 22 '20 at 16:50
  • If you take a look at all of your function that are supposed to return values, you failed to do so. For example, the `bool Book::operator==` is supposed to return a `bool` but doesn't return anything. – PaulMcKenzie Dec 22 '20 at 16:56
  • 1
    i fixed all the return types except the bool one and finally it worked thank you so much. – Mohamed Hesham Dec 22 '20 at 17:26