C++ OOP Abstract Class - Access violation writing location - c++

I have an UserAcount class that has an abstract class ContBancar, and other class Banca which reads some users from a file (with method void Banca::citire_conturi()). When it reads the users, I get an error "Access violation writing location" in ContBancar at void setBal(double bal) { _balanta = bal; }. Thx for help !
PS : The file has only one line : 1CBS Dragos 0 dragos12! Gzpvia01= .
Also, i want to make a bank account system, with an user class that has an bank account class which inherits 3 types of a bank accounts, and a bank class which reads some users from a file or put them on it.
class UserAccount
{
private:
std::string _nume, _user, _pass;
std::string _cod_us;
std::shared_ptr <ContBancar> _cont;
public:
void setUser(std::string user) { _user = user; }
void setPass(std::string pass) { _pass = pass; }
void setNume(std::string nume) { _nume = nume; }
void setCodUs(std::string cod) { _cod_us = cod; }
void setContBal(double balanta) { (*_cont).setBal(balanta); }
std::string getUser() const { return _user; }
std::string getPass() const { return _pass; }
std::string getNume() const { return _nume; }
std::string getCodUs() const { return _cod_us; }
double getContBal() const { return (*_cont).getBal(); }
void setContBancar();
};
void UserAccount::setContBancar()
{
if (_cod_us == "1CBS")
_cont.reset(new ContBancarSilver());
else if (_cod_us == "2CBG")
_cont.reset(new ContBancarGold());
else
_cont.reset(new ContBancarDiamond());
}
class ContBancar
{
protected:
double _balanta;
public:
void setBal(double bal) { _balanta = bal; }
double getBal() { return _balanta; }
virtual bool depozitare(unsigned int) = 0;
virtual bool retragere(unsigned int) = 0;
};
class Banca
{
private:
std::vector<UserAccount> vec;
public:
void citire_conturi();
};
void Banca::citire_conturi()
{
std::ifstream file;
file.open("Baza_Date.txt");
UserAccount temp;
std::string cod, nume, user, pass;
double balanta;
while (file >> cod >> nume >> balanta >> user >> pass)
{
temp.setCodUs(cod);
temp.setNume(nume);
temp.setContBal(balanta);
temp.setUser(user);
temp.setPass(pass);
vec.push_back(temp);
}
file.close();
}
class ContBancarSilver : public ContBancar
{
private:
static constexpr unsigned int max_balanta = 5000;
static constexpr unsigned int max_depozitare = 2500;
static constexpr unsigned int max_retragere = 1000;
static constexpr double tax_retragere = 0.08;
static constexpr double bonus_depunere = 0.03;
static constexpr double bonus_tax_retragere = 0.05;
static constexpr unsigned int max_depozitari = 1;
static constexpr unsigned int max_retrageri = 1;
public:
virtual bool depozitare(unsigned int) override;
virtual bool retragere(unsigned int) override;
};

Based on available informationyou should fix your code like this:
class UserAccount
{
.....
void setCodUs(std::string cod) {
_cod_us = cod;
setContBancar();
}
void setContBal(double balanta) {
if (!_cont) setContBancar(); // lazy initialization
_cont->setBal(balanta);
}
...
};
void UserAccount::setContBancar()
{
if (_cod_us == "1CBS")
_cont = std::make_shared<ContBancarSilver>();
else if (_cod_us == "2CBG")
_cont = std::make_shared<ContBancarGold>();
else
_cont = std::make_shared<ContBancarDiamond>();
}
Note I do not understand what kind of logic you are implementing. This changes just ensured that _cont is initialized and up to date with _cod_us.
Please stop use explicitly new and delete. Everything can be created by std::make_shared and std::make_unique and containers like std::vector.

Related

Passing a class object into a templated classes private member scope

Hi I'm new to c++ and trying to learn something. maybe it can't be done. but I want to:
create an Employee class that records all employees, and their information (see my code below).
Then I want to make a templated class for a linked list. inside the private scope of this class, I will have a "T data" type. I want my constructor to instantiate an "Employee" every time a LinkedList object is created in the main. I hope that makes sense. I have my code working the way I set it up now. However, I'm not necessarily templating it the way I want.
template <class T>
class Employees { //Parent
private:
int EmployeeID;
double Paycheck;
int Hours;
double Payrate;
std::string Employeename;
public:
Employees(int ID, double Prate, std::string EName) {
EmployeeID = ID;
Payrate = Prate;
Employeename = EName;
Hours = 0; //our constructor can just give each Employee 0 hours.
Paycheck = 0.00;
}
Employees() {
EmployeeID = 0;
Payrate = 0.0;
Employeename = "N/A";
Hours = 0;
Paycheck = 0.00;
}
void setPaycheck() {
std::cout << std::fixed;
std::cout << std::setprecision(2);
double i = Payrate;
i = i * 100;
i = i * Hours;
i = i / 100;
Paycheck = i;
//so I'm not sure why I couldn't just cast the double, but the complier kept rounding down each time.
// I had to make a conversion of my decimal into a whole number and then go back and divide it to get the
// paycheck amount.
};
void setEMPname(std::string Name) {
Employeename = Name;
}
void setPayrate(double payrate) {
Payrate = payrate;
}
void setEMPid(int IDnum) {
EmployeeID = IDnum;
}
void setHOURS(int hours) {
Hours += hours;
}
int IDReturn() { return EmployeeID; }
int HoursReturn() { return Hours; }
double PaycheckReturn() { return Paycheck; }
double PayrateReturn() { return Payrate; }
std::string NameReturn() { return Employeename; }
};
template <class T>
class LinkedLists :Employees<T> { //child
friend class Employees<T>;
private:
////I want change the object below to "T data"
Employees<T> EmployeeObject; //contains all the employee information
LinkedLists<T>* nextlink;
LinkedLists<T>* prevlink;
public:
LinkedLists() {
EmployeeObject;
nextlink = nullptr;
prevlink = nullptr;
}
void setname(std::string Name) {
EmployeeObject.setEMPname(Name);
}
void setPrate(double payrate) {
EmployeeObject.setPayrate(payrate);
}
void setid(int IDnum) {
EmployeeObject.setEMPid(IDnum);
}
void setPayCheck() { EmployeeObject.setPaycheck(); }
LinkedLists<T>*& setLinkforward() {
return nextlink;
}
LinkedLists<T>*& setLinkbackward() {
return prevlink;
}
int idReturn() { return EmployeeObject.IDReturn(); }
double payrateReturn() { return EmployeeObject.PayrateReturn(); }
std::string nameReturn() { return EmployeeObject.NameReturn(); }
void AddHours(int Hours) { EmployeeObject.setHOURS(Hours); }
int ReturnHours() { return EmployeeObject.HoursReturn(); }
double ReturnPayCheck() {
return EmployeeObject.PaycheckReturn();
}
};

C++ Inheritance of functions, passing in arguments

Base class : Employee
Derived class : Regular
Employee.cpp
void Employee::setValue(string id, string name, double s, int n)
{
empID = id;
empName = name;
salary = s;
}
Regular.cpp
void Regular::setValue(string id, string name, double s, int n)
{
annualLeave = n;
}
Employee::setValue() only stores the first 3 arguments passed in, but not int n, too.
I'm supposed to inherit that setValue() in Regular::setValue() and then just pass in the arguments, but this time store int n to annualLeave.
How do I do that?
Or, is there a way for me to set int n in the base class for the child class?
You can call the base class's implementation:
void Regular::setValue(string id, string name, double s, int n) {
annualLeave = n;
return Employee::setValue(std::move(id), std::move(name), s);
}
Otherwise, make base class polymorphic:
struct Employee {
void setValue(string id, string name, double s, int n) {
empID = std::move(id);
empName = std::move(name);
salary = s;
setLeave(n);
}
virtual ~Employee() {}
protected:
virtual void setLeave(int) = 0;
string empID;
string empName;
double salary;
};
struct Regular: Employee {
private:
void setLeave(int n) override { annualLeave = n; }
int annualLeave;
};
If necessary to keep a single-signature setValue function, it is possible to do it like that:
-
Includes:
#include <any>
#include <map>
#include <string>
-
Employee.h:
class CEmployee
{
protected:
virtual void setValue(std::map<std::string, std::any> &info);
int m_empID = 0;
std::string m_empName = {'\0'};
int m_salary = 0;
}
Employee.cpp:
void CEmployee::setValue(std::map<std::string, std::any> &info)
{
std::any item;
item = info["empID"];
if (item.has_value())
m_empID = std::any_cast<int>(item); // int
item = info["empName"];
if (item.has_value())
m_empName = std::any_cast<std::string>(item); // std::string
item = info["salary"];
if (item.has_value())
m_salary = std::any_cast<int>(item); // int
}
-
Regular.h:
class CRegular : public CEmployee
{
public:
void setValue(std::map<std::string, std::any> &info) override;
protected:
std::string m_annualLeave = {'\0'};
}
Regular.cpp:
void CRegular::setValue(std::map<std::string, std::any> &info)
{
std::any item;
CEmployee::setValue(info);
item = info["annualLeave"];
if (item.has_value())
m_annualLeave = std::any_cast<std::string>(item); // std::string
}
-
& call it like that:
void MyClass::HardcodedExample()
{
CRegular regular_employee;
std::map<std::string, std::any> info, update;
info["empID"] = { 100 };
info["empName"] = { std::string("Trump") };
info["salary"] = { 1000000 };
info["annualLeave"] = { std::string("29 Jul 2018") };
regular_employee.setValue(info); // Set all info
// Or:
update["annualLeave"] = { std::string("29 Dec 2018") };
regular_employee.setValue(update); // Update just "annualLeave"
// Or:
update["salary"] = { 1200000 };
update["annualLeave"] = { std::string("04 Jul 2018") };
regular_employee.setValue(update); // Update "salary" & "annualLeave"
}
-
Otherwise, setValue with 3 parameters to base-class, & with 4 parameters to the derived-class (that calls to the base-class with the 3 parameters and sets by itself the 4th one) - similar to what #RemyLebeauis offers - is a better solution.
-
& better to use #define / enum keys instead of string-keys (& change the key-type of the map accordingly), but this is a different issue.

Should be a virtual destructor? But how?

A program that stores a phone company's consumers data in a linked list. At the end it displays the bill for each human. I have the following codes:
class BaseTypeOfContract
{
private:
int minutePrice;
int SMSPrice;
public:
void setminutePrice(int x) { minutePrice = x; }
void setSMSPrice(int x) { SMSPrice = x; }
virtual int calculateBill(int talkedMinutes, int sentSMS) = 0;
int getminutePrice() const { return minutePrice; }
int getSMSPrice() const { return SMSPrice; }
};
class SMSBaseType : public BaseTypeOfContract
{
private:
int freeSMS;
public:
SMSBaseType(int minutePrice, int SMSPrice, int freeSMS)
{
setminutePrice(minutePrice);
setSMSPrice(SMSPrice);
setfreeSMS(freeSMS);
}
public:
void setfreeSMS(int free) { this->freeSMS = free; }
virtual int calculateBill(int talkedMinutes, int sentSMS)
{
int billedSMS = (freeSMS > sentSMS) ? 0 : sentSMS - freeSMS;
return talkedMinutes * getminutePrice() + billedSMS * getSMSPrice();
}
};
class Base : public BaseTypeOfContract
{
public:
Base()
{
setminutePrice(30);
setSMSPrice(10);
}
virtual int calculateBill(int talkedMinutes, int sentSMS) { return talkedMinutes * getminutePrice() + sentSMS * getSMSPrice();}
};
class SMSMax : public SMSBaseType
{
public:
SMSMax() : SMSBaseType(20, 5, 150) {}
};
class MobiNET: public SMSBaseType
{
public:
MobiNET() : SMSBaseType(10, 15, 25) {}
};
Client's class:
class Client
{
public:
std::string name;
std::string phoneNumber;
BaseTypeOfContract* typeOfContract;
int talkedMinutes;
int sentSMS;
Client *next;
public:
Client(){}
Client(std::string n, std::string p, int bp, int ks) : name(n), phoneNumber(p), talkedMinutes(bp), sentSMS(ks) {}
void preSetPlan(std::string s)
{
if (s == "MobiNET")
this->typeOfContract = new MobiNET();
else if (s == "SMSMax")
this->typeOfContract = new SMSMax();
else this->typeOfContract = new Base();
}
std::string getname() const { return name; }
std::string getphoneNumber() const { return phoneNumber; }
void setname(std::string n) { name = n; }
void setphoneNumber(std::string pn) { phoneNumber = pn; }
void settalkedMinutes(int bp) { talkedMinutes = bp; }
void setsentSMS(int SSMS) { sentSMS = SSMS; }
int getBill() const { return this->typeOfContract->calculateBill(talkedMinutes, sentSMS); }
};
I read the data from 2 files. First file contains the name, phone number, type of contract. Second file contains the phone number, talked minutes and sent SMS.
Client* file_read_in()
{
std::ifstream ClientData;
ClientData.open("clients.txt");
Client *first = new Client;
first = NULL;
while (!ClientData.eof())
{
std::string name, phoneNumber, typeOfContract;
ClientData >> name;
ClientData >> phoneNumber;
ClientData >> typeOfContract;
std::ifstream ClientTalkedSent;
ClientTalkedSent.open("used.txt");
while(!ClientTalkedSent.eof())
{
std::string phoneNumber2;
ClientTalkedSent >> phoneNumber2;
if (phoneNumber2 == phoneNumber)
{
int talkedMinutes, sentSMS;
ClientTalkedSent >> talkedMinutes;
ClientTalkedSent >> sentSMS;
Client* tmp = new Client(name, phoneNumber, talkedMinutes, sentSMS);
tmp->preSetPlan(typeOfContract);
tmp->next = NULL;
if (first == NULL)
{
first = tmp;
}
else
{
Client *cond = first;
while (cond->next != NULL) cond = cond->next;
cond->next = tmp;
}
}
}
ClientTalkedSent.close();
}
ClientData.close();
return first;
}
And the main:
int main()
{
Client* first = file_read_in();
while(first != NULL)
{
std::cout << first->getname() << " " << first->getphoneNumber() << " " << first->getBill() << std::endl;
first = first->next;
}
return 0;
}
My problem that I should free the allocated memory but I got on idea how. Which class' destructor should do the dirty job. I would appreciate if someone could use my code, to show how the "destructor inheritance" works.
Sorry for my bad english and thanks for the help. This site helped me alot of times, but for this problem I did not find a solution.
If you have a pointer BaseTypeOfContract* typeOfContract; that is used to point to different derived classes, then BaseTypeOfContract needs to have a virtual destructor for delete typeOfContract to work.
And as Client seems to create the objects pointed to, it also ought to be responsible for cleaning them up. Either by using delete typeOfContract; in its destructor, or by storing a smart pointer to get the work done automatically.
The other part is that each Client stores a pointer to the next Client. That seems like not the best design. In real life it is not at all like each person knowing who is the next person that buys a cell phone in the same store. :-)
You would be much better of with a container, like std::vector<Client>, that would also handle the lifetime of the Client objects.

Error: identifier classname is undefined? Getting this for all the classes I've made in the file

This is the code
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
class FIXML {
private: Order Order_object = new Order();
public:
Order getOrder_object()
{
return Order_object;
}
void setOrder_object(Order Order_object)
{
this->Order_object = Order_object;
}
};
class Order {
public:
string ClOrdID = "123456";
string Side = "2";
string TransactTm = "2001-09-11T09:30:47-05:00";
string OrdTyp = "2";
string Px = "93.25";
string Acct = "26522154";
Hdr Hdr_object = Hdr();
Instrmt Instrmt_object = Instrmt();
OrdQty OrdQty_object = OrdQty();
public:
string getClOrdID()
{
return ClOrdID;
}
string getSide()
{
return Side;
}
string getTransactTm()
{
return TransactTm;
}
string getOrdTyp()
{
return OrdTyp;
}
string getPx()
{
return Px;
}
string getAcct()
{
return Acct;
}
Hdr getHdr_object()
{
return Hdr_object;
}
Instrmt getInstrmt_object()
{
return Instrmt_object;
}
OrdQty getOrdQty_object()
{
return OrdQty_object;
}
void setClOrdID(string ClOrdID)
{
this->ClOrdID = ClOrdID;
}
void setSide(string Side)
{
this->Side = Side;
}
void setTransactTm(string TransactTm)
{
this->TransactTm = TransactTm;
}
void setOrdTyp(string OrdTyp)
{
this->OrdTyp = OrdTyp;
}
void setPx(string Px)
{
this->Px = Px;
}
void setAcct(string Acct)
{
this->Acct = Acct;
}
void setHdr_object(Hdr Hdr_object)
{
this->Hdr_object = Hdr_object;
}
void setInstrmt_object(Instrmt Instrmt_object)
{
this->Instrmt_object = Instrmt_object;
}
void setOrdQty_object(OrdQty OrdQty_object)
{
this->OrdQty_object = OrdQty_object;
}
};
class Hdr {
private:
string Snt = "2001-09-11T09:30:47-05:00";
string PosDup = "N";
string PosRsnd = "N";
string SeqNum = "521";
Sndr Sndr_object = Sndr();
Tgt Tgt_object = Tgt();
public:
string getSnt()
{
return Snt;
}
string getPosDup()
{
return PosDup;
}
string getPosRsnd()
{
return PosRsnd;
}
string getSeqNum()
{
return SeqNum;
}
Sndr getSndr_object()
{
return Sndr_object;
}
Tgt getTgt_object()
{
return Tgt_object;
}
void setSnt(string Snt)
{
this->Snt = Snt;
}
void setPosDup(string PosDup)
{
this->PosDup = PosDup;
}
void setPosRsnd(string PosRsnd)
{
this->PosRsnd = PosRsnd;
}
void setSeqNum(string SeqNum)
{
this->SeqNum = SeqNum;
}
void setSndr_object(Sndr Sndr_object)
{
this->Sndr_object = Sndr_object;
}
void setTgt_object(Tgt Tgt_object)
{
this->Tgt_object = Tgt_object;
}
};
class Sndr {
private:
string ID = "AFUNDMGR";
public:
string getID()
{
return ID;
}
void setID(string ID)
{
this->ID = ID;
}
};
class Tgt {
private:
string ID = "ABROKER";
public:
string getID()
{
return ID;
}
void setID(string ID)
{
this->ID = ID;
}
};
class Instrmt {
private:
string Sym = "IBM";
string ID = "459200101";
string IDSrc = "1";
public:
string getSym()
{
return Sym;
}
string getID()
{
return ID;
}
string getIDSrc()
{
return IDSrc;
}
void setSym(string Sym)
{
this->Sym = Sym;
}
void setID(string ID)
{
this->ID = ID;
}
void setIDSrc(string IDSrc)
{
this->IDSrc = IDSrc;
}
};
class OrdQty {
private:
string Qty = "1000";
public:
string getQty()
{
return Qty;
}
void setQty(string Qty)
{
this->Qty = Qty;
}
};
return 0;
}
All the classes I've declared, whether it's Order, Tgt, Sndr. Whenever I make a new instance of these classes, I get the error "Error: identifier classname is undefined"
Thanks in advance
Try declaring them (a) before you use them, and (b) outside of any function:
#include <iostream>
class Test
{
public:
Test() { std::cout << "Test!" << std::endl; }
};
int main()
{
Test t;
}
Once you finish reordering them based on which classes are used by which, it may end up like this:
class OrdQty {
// ...
};
class Instrmt {
// ...
};
class Sndr {
// ...
};
class Tgt {
// ...
};
class Hdr {
// ...
};
class Order {
// ...
};
class FIXML {
// ...
};
int main()
{
return 0;
}
Once you finish that, you'll find that this line is incorrect:
private: Order Order_object = new Order();
You can't initialize a member of a class like this. You'll need to do this in the constructor, copy constructor, and assignment operator, and then clean it up in the destructor.

Working with a void pointer

Given the following scenario where my data might be of different type based on some condition.
class myClass {
public:
myclass() {
if (condition1) {
bool boolValue = false;
data = boolValue;
} else if (condition2) {
int intValue = 0;
data = intValue;
} else if (condition3) {
unsigned int unsignedIntValue = 0;
data = unsignedIntValue;
} else if (condition4) {
long longValue = 0;
data = longValue;
} else if (condition5) {
double doubleValue = 0.0;
data = doubleValue;
} else if (condition6) {
float floatValue = 0.0;
data = floatValue;
} else if (condition7) {
char *buffer = new char[10];
data = buffer;
}
}
void* getData() const { return data; }
private:
void *data;
}
As it happens the value that my void pointer points to is strictly within each statement. Therefore what is returned with getData() might not be valid. If I do get the data it is simply because the memory location where I point to is not yet written over.
The solution I have come up with is this:
class myClass {
public:
myclass() {
if (condition1) {
boolValue = false;
data = boolValue;
} else if (condition2) {
intValue = 0;
data = intValue;
} else if (condition3) {
unsignedIntValue = 0;
data = unsignedIntValue;
} else if (condition4) {
longValue = 0;
data = longValue;
} else if (condition5) {
doubleValue = 0.0;
data = doubleValue;
} else if (condition6) {
floatValue = 0.0;
data = floatValue;
} else if (condition7) {
buffer = new char[10];
data = buffer;
}
}
void* getData() const { return data; }
private:
void *data;
bool boolValue;
int intValue;
unsigned int unsignedIntValue;
long longValue;
double doubleValue;
float floatValue;
char *buffer;
}
I was thinking there must be a more elegant way to do this. Any suggestions?
You could use a union to save a few bits in memory, and then use pointer casting to get the value from the union:
#include<iostream>
using namespace std;
class myClass {
public:
myClass(char *str){
data.str = str;
}
myClass(double d){
data.d = d;
}
myClass(float f){
data.f = f;
}
void *getData() { return (void*)&data; }
private:
union {
double d;
float f;
char *str;
} data;
};
int main(){
myClass c(2.0);
cout << *(double*)c.getData() << endl;
myClass f(3.0f);
cout << *(float*)f.getData() << endl;
myClass s("test");
cout << *(char**)s.getData() << endl;
system("pause");
}
/* prints
2
3
test
*/
If you don't need to change the type of the data after you create an object, then you could use a template class:
template <typename T>
class myBaseClass {
public:
// Declare common functions here.
T getData()
{ return data; }
protected:
T data;
protected:
// Disallow constructing instances of this class outside the child classes.
myBaseClass(T val) : data(val) { }
};
template <typename T>
class myClass: public myBaseClass<T> {
public:
myClass() : myBaseClass<T>(0) { }
};
You then specialize for char*:
template <>
class myClass<char*>: public myBaseClass<char*> {
public:
myClass() : myBaseClass(new char[10]) { }
};
You then create instances like this:
myClass<int> a;
myClass<float> b;
myClass<char*> c;
// etc.
int i = a.getData();
float f = b.getData();
char* str = c.getData();