This question already has answers here:
Why can I not push_back a unique_ptr into a vector?
(2 answers)
Closed 3 years ago.
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);
}
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&&
Related
I'm fairly new to C++ and I've been working on an assignment where I'm tasked with displaying given social media posts with classes and objects. I was doing okay but I keep getting this error that says No instance of constructor "Post::Post" matches argument list. I think I'm missing something simple and I was hoping someone could point out to me.`
Main.cpp
#include <iostream>
#include "Post.hpp"
#include <string>
int main() {
Post post1("Chicken came before the egg confirmed!", "A new story just released where we finally get the answer of who came first."); //error appears on this line
std::cout << post1.getTitle() << std::endl;
std::cout << post1.getBody() << std::endl;
post1.getTimeStamp();
post1.setTitle("Actually the egg came first!");
post1.setBody("Ok, maybe the decision is not final.");
std::cout << std::endl;
post1.displayPost();
Post.hpp
#ifndef POST_HPP
#define POST_HPP
#include <string>
#include <ctime>
class Post {
private:
std::string Title;
std::string Body;
time_t Time;
public:
void setTitle(string title);
string getTitle();
void setBody(string body);
string getBody();
void setTimeStamp();
int getTimeStamp();
void displayPost();
}
#endif
Post.cpp
#include "Post.hpp"
#include <string>
class Post {
private:
string Title;
string Body;
time_t Time;
public:
void setTitle(string title){
Title = title;
}
string getTitle(){
return Title;
}
void setBody(string body){
Body = body;
}
string getBody(){
return Body;
}
void setTimeStamp(int time){
Time = time;
}
void getTimeStamp(){
struct tm *timestamp;
time_t ltime;
time(<ime);
timestamp = localtime(<ime);
printf("Today is %s",
asctime(timestamp));
}
void displayPost(){
cout << Title << Time << " :" << Body <<endl;
}
};
You need to add constructor to your code that takes two string parameters in your post.hpp file, something like:
public:
Post(const std::string &s1, const std::string &s2);
You forgot to code a custom constructor of your class Code. It goes like this:
class Post {
public:
Post(string title, string body) : Title(title), Body(body){} // It creates an instance of the class Post
// Add member functions and variables below
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I want to create a Student object in C++ and it has the properties of name, major, age and id. The object initialization will be done in the main() part and Student object has the get and set methods for all the constructors. I want to print the student objects in the main() part but I get this error:
in C++98 's1' must be initialized by constructor, not by '{...}'
I am using GNU GCC Complier in Codeblocks. I haven't written specifically any code for compiling or debugging.
I tried to initialize the objects by assigning them to this, making them null, giving them zero and random values but they haven't worked.
Student.h file
#ifndef STUDENT_H
#define STUDENT_H
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
string name, major;
int age, id;
Student(string name, string major, int age, int id);
string getName();
void setName(string name);
string getMajor();
void setMajor(string major);
int getAge();
void setAge(int age);
int getId();
void setId(int id);
};
ostream & operator << (ostream &out, Student &s);
#endif // STUDENT_H
Student.cpp file
#include "Student.h"
#include <iostream>
using namespace std;
Student::Student(string newName, string newMajor, int newAge, int newId)
{
name = newName;
major = newMajor;
age = newAge;
id = newId;
}
string Student::getName(){
return name;
}
void Student::setName(string newName){
name = newName;
}
string Student::getMajor(){
return major;
}
void Student::setMajor(string newMajor){
major = newMajor;
}
int Student::getAge(){
return age;
}
void Student::setAge(int newAge){
age = newAge;
}
int Student::getId(){
return id;
}
void Student::setId(int newId){
id = newId;
}
ostream & operator << (ostream &out, Student &s)
{
out << "Name: " << s.getName() << " Major: " << s.getMajor() << " Age: " << s.getAge() << " Id:" << s.getId() << endl;
return out;
}
Main.cpp file
#include <iostream>
#include <string>
#include "Student.h"
using namespace std;
int main()
{
Student s1 {"John","MATH",24,123456};
Student s2 {"Steve","ENG",22,654321};
cout << s1 << endl;
cout << s2 << endl;
return 0;
}
I expect to print out the properties of the students as a list but when I run it the program crashes and I get this error:
** in C++98 's1' must be initialized by constructor, not by '{...}' **
I fixed my problem. There were a few problems so here I will explain my solutions in detail.
1-My code is written in C++11 syntax but I was using C++98 syntax so I changed my complier to C++11.
2-My initialization was wrong, I used new variables such as newName, newAge... to change the properties of the Student object.
3-My set methods were wrong so I changed them similar to my initialization.
4-I added an opeator to print out properties more easily.
All the changes are updated for the code in the question
I have a string to be printed via a function. I am using turbo-c compiler.
While using procedural method I am able to do it from following code :
#include <iostream.h>
#include <conio.h>
void strr(char name[]);
void main(){
char name1[10];
cout << "Enter name";
cin >> name1;
strr(name1);
getch();
}
void strr(char name[]){
cout << name;
}
But With oop method I am not able to print the string. My Code is :
#include <iostream.h>
#include <conio.h>
class name{
public: void strr(char name[]);
};
void main(){
char name1[10];
cout << "Enter name";
cin >> name1;
strr(name1);
getch();
}
void name::strr(char name[]){
cout << name;
}
With oop method I am getting error Function 'strr' hould have a prototype.
Since your function is defined inside the class, you need an object/instance of the name class to invoke it :
name obj;
cin >> name1;
obj.strr(name1);
Alternatively, if you declare the function as static, then you can invoke it without a class-instance, since the function is a class-function :
class name{
public: static void strr(char name[]) {cout << name << endl;}
};
...
cin >> name1
name::strr(name1);
Try this
name :: void strr(char name[])
{}
main.cpp:
#include "Login.h"
int main () {
Login();
}
Login.h:
#ifndef LOGIN_H
#define LOGIN_H
#include <string>
#include <iostream>
using namespace std;
class Login
{
public:
Login ();
string getInput () {
return input;
}
void setInput (string x) {
x=input;
}
private:
string input;
};
#endif
Login.cpp:
#include "Login.h"
Login::Login ()
{
Login lo;
lo.setInput("hello");
cout << lo.getInput();
};
I'm just learning to program and I'm trying to make a simple program to display input, but to use a class and object to do it, so I can learn how and ultimately make a program that starts with a login (hence all the "login" names).
When I run this it just crashes, and I have no idea why, or how i would search for a solution to this online, because I don't know even remotely what the problem is.
My question is two-fold:
1. Why is this just crashing?
2. How could I set the parameter in lo.setInput to a user input? (cin)
For 1,
Login::Login()
{
Login lo; // here
You're recursively-calling Login constructor infinitely. When Login lo, the constructor Login::Login is called. it makes its new Login object, and repeat...
Probably you want this:
Login::Login()
{
setInput("hello");
cout << getInput();
}
For 2, just receive input and call with it.
string str;
getline(cin, str);
setInput(str);
In addition, C++ is too hard for newbies to study at first. I recommend you to start with other easier language, such as C, python, etc.
The problem is that your constructor recursively calls itself when it creates within its body local object lo
Login::Login ()
{
Login lo;
lo.setInput("hello");
cout << lo.getInput();
};
Change it the following way
Login::Login ()
{
setInput("hello");
cout << getInput();
};
Though it would be better to define it like (or to allow the compiler to define it itself)
Login::Login () {}
and in main to write
Login lo;
lo.setInput("hello");
cout << lo.getInput();
Also function setInput is invalid
void setInput (string x) {
x=input;
}
There must be
void setInput (string x) {
input = x;
}
The class could be defined like
class Login
{
public:
Login() = default;
Login( const std::string &s ) : input( s ) {}
std::string getInput () const { return input; }
void setInput( const std::string &s ) { input = s; }
private:
std::string input;
};
You may want to create an instance of the Login class and use its methods:
int main(void)
{
Login my_login;
cout << my_login.getInput();
return 0;
}
Another possibility is to create static methods within the Login class. This would essentially be like grouping functions and variables into one package:
class Login
{
public:
static std::string getLoginText(void)
{
std::string text;
cout << "Enter login ID: ";
cin >> text;
return text;
}
};
int main(void)
{
std::string login_text;
login_text = Login::getLoginText();
cout << "Person " << login_text << " is logged in\n";
return 0;
}
Your original main program is confusing as to whether you want to create a temporary instance of the Login class, or call a function called Login. The above techniques make your code more readable by explicitly stating your intentions, rather than relying on unconventional techniques.
I currently have an abstract User class and a Student class which inherits from user. I'm attempting to initialize an instance of the Student class from main. I'm receiving this error
Undefined symbols for architecture i386:
"Student::Student()", referenced from:
_main in ccJo7npg.o
"Student::~Student()", referenced from:
_main in ccJo7npg.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
User Class:
#include <iostream>
#import <stdio.h>
#import <string.h>
using namespace std;
class User
{
public:
void setName(const string n)
{
name = n;
}
string getName()
{
return name;
}
void setUsername(const string u)
{
username = u;
}
string getUsername()
{
return username;
}
void setPassword(const string p)
{
password = p;
}
string getPassword()
{
return password;
}
void setID(const int ID)
{
this->ID=ID;
}
int getID()
{
return ID;
}
void setClassID(const int cid)
{
classID=cid;
}
int getClassID()
{
return classID;
}
void logOut()
{
cout<<"you have logged out"<<endl;
}
void print()
{
cout<< "Student : "<< ID << name << " "<< username << " " << password << endl;
}
virtual void menu()=0;
protected:
int classID, ID;
string name, username, password;
};
Student Class:
#include <iostream>
#include "User.h"
using namespace std;
class Student: public User
{
public:
Student()
{
classID=0;
ID=0;
username="";
name="";
password="";
}
~Student()
{
cout<<"destructor"<<endl;
}
void studyDeck(const int i)
{
}
void viewScores(const int)
{
}
void viewScores()
{
}
virtual void menu()
{
cout << "Student menu" << endl;
}
};
Main.cpp:
#include <iostream>
#include "User.h"
#include "Student.h"
using namespace std;
int main()
{
Student s;
return 0;
}
I'm compiling with g++ with " g++ User.cpp Student.cpp main.cpp "
Thanks!
GCC is not producing code for the Student constructor and destructor because they are defined inside of the class declaration. That's why those symbols are missing and generating a link error. At a minimum, you need to move the function bodies for the Student constructor and destructor outside of the class declaration and provide just the signature (no body) in the definition:
class Student: public User
{
Student();
~Student();
...
};
You would define these function bodies in Student.cpp after the class definition as follows:
Student::Student()
{
classID=0;
ID=0;
username="";
name="";
password="";
}
Student::~Student()
{
cout<<"destructor"<<endl;
}
Though it's not necessary, you should separate all of the function definitions from their implementation. To do this, you would omit the class definition from the Student.cpp file; and instead include Student.h in Student.cpp (even though you didn't post Student.h, it appears to be correct or the program would not have compiled). In other words, "Student.h" would contain "class Student { ... };" with just function signatures and no function bodies inside the braces and "Student.cpp" would contain all of the function definitions with bodies such as:
void Student::menu()
{
cout << "Student menu" << endl;
}
If you do this, you will also need #ifndef guards in the .h files as Kevin Grant explained.
You would treat User.cpp and User.h in the same way.