0

I am trying to create one vector for two types of users. Admin and Customer who are both derived from an abstract class, BaseUser. However I tried some of the answers provided online but I can't seem to make this work. I keep getting error: use of delete function 'std::unique_ptr<....

I am still struggling with fully grasping the concept of pointers so that could be why im stuck with this problem.

#ifndef BASEUSER_H
#define BASEUSER_H

#include <string>

class BaseUser 
{
    private:
        int id;
        int idCounter = 0;
        std::string fullname;
        std::string username;
        std::string password;

    protected:
        bool isAdmin;

    public:
        BaseUser();
        BaseUser(std::string fullname, std::string username, std::string password);

        virtual void setIsAdmin(bool isAdmin) = 0; 
        void setID(int id);

        void setFullname(std::string fullname);
        void setUsername(std::string username);
        void setPassword(std::string password);

        unsigned long int getID();
        std::string getFullname();
        std::string getUsername();
        std::string getPassword();


};

#endif
#ifndef ADMIN_H
#define ADMIN_H

#include "BaseUser.h"

class Admin : public BaseUser
{
    public:
        Admin(std::string fullname,std::string username,std::string password);

        void setIsAdmin(bool isAdmin); 
        bool getIsAdmin();
};

#endif
#ifndef USERMANAGER_H
#define USERMANAGER_H

#include "Admin.h"
#include "Customer.h"
#include <vector>
#include <memory>

class UserManager
{
    private:
        std::vector<std::unique_ptr<BaseUser>> users;
        bool isAuthenticated;

    public:
        std::vector<std::unique_ptr<BaseUser>> getUsers();

        bool login(std::string name, std::string password);
        bool logout();

        void createAdmin(Admin);
        // void createCustomer(Customer);

};

#endif

Object creation method declaration inside the usermanager class:

void UserManager::createAdmin(Admin admin))
{   
    users.push_back( move(admin) )
}

I also tried to push using make_unique, but still the same error.

View that return the object to the createAdmin() method:

// View.cpp

Admin View::createAdminView()
{
    string fullname, username, password;

    cout << "~ Register Admin ~" << endl << endl;

    cout << "Name: ";
    cin.ignore();
    getline(cin, fullname);

    cout << "Username: ";
    cin >> username;

    cout << "Password: ";
    cin >> password;

    return Admin(fullname, username, password);
}
Manu Febie
  • 31
  • 4
  • @Ron this has little to do with the Rule of Zero (or lesser variations), which states what special functions you should implement when implementing other special functions. – rubenvb Jun 17 '19 at 15:01
  • 3
    You are pushing a value type `Admin` to `vector` of `unique_ptr`. You should push (with move) a `unique_ptr` (this will be silently converted to `unique_ptr`)! – Marek R Jun 17 '19 at 15:08

1 Answers1

1

try changing createAdmin into this:

void UserManager::createAdmin(Admin admin)
{   
    users.push_back( std::make_unique<Admin>(admin) );
}

push_back of a vector<T> wants a const T& or (in this case) a T&&

sp2danny
  • 6,824
  • 2
  • 27
  • 49
  • 1
    Why not change the argument to get the unique_ptr? – Adriel Jr Jun 17 '19 at 15:14
  • @AdrielJr: I wanted both to display the use of `make_unique`, and make a minimal change. – sp2danny Jun 17 '19 at 15:17
  • I see to many copies of admin here: first when passing admin by value, and then when creating a unique pointer based on admin. Also, since c++11 I always use emplace_back. In this case it should not make any difference since it is a vector of pointers, but when dealing with objects, it may avoid another copy. – Adriel Jr Jun 17 '19 at 15:23