I have to do a little c++ reflection in my way, by creating a pointer for each property of my class(I have create a tool to help me generate corresponding c++ code), but surprise, Building on x86 mode worked fine, but on x64 mode it's crashed, I have no idea why! here is my code.
Product.h File
class Product
{
public:
int ID;
std::string Designation;
};
class Property
{
public:
std::string Name;
int Shift;
};
class ProductSchema
{
private:
ProductSchema();
public:
static ProductSchema* Default();
ProductSchema(const ProductSchema& other) = delete;
Property ID;
Property Designation;
Property Prix;
};
Product.cpp File
ProductSchema::ProductSchema()
{
Product* p = new Product();
ID.Name = "ID";
ID.Shift = (int)(int*)&p->ID - (int)p;
Designation.Name = "Designation";
Designation.Shift = (int)(int*)&p->Designation - (int)p;
}
ProductSchema* ProductSchema::Default()
{
static ProductSchema* instance_;
if (instance_ == nullptr)
instance_ = new ProductSchema;
return instance_;
}
main.h file
int main()
{
for (int i = 0; i < 10000; i++)
{
Product* p = new Product();
int* pID = (int*)((unsigned long int)p + ProductSchema::Default()->ID.Shift);
*pID = i; // <--- error here
}
}
Your ProductSchema class, and your main(), are leaking the objects they new.
You don't need to create an object at runtime to calculate offsets to its members, you can use offsetof() at compile-time instead.
Don't use int or unsigned long to perform calculations on pointers. They are not guaranteed to be large enough. Use (u)intptr_t instead.
Your singleton is not initializing its instance_ pointer before using it. It does not need to use dynamic memory at all.
Try this instead:
class Product
{
public:
int ID;
std::string Designation;
};
struct Property
{
std::string Name;
int Shift;
};
class ProductSchema
{
private:
ProductSchema();
public:
static ProductSchema& Default();
ProductSchema(const ProductSchema& other) = delete;
Property ID;
Property Designation;
Property Prix;
};
ProductSchema::ProductSchema()
{
ID.Name = "ID";
ID.Shift = offsetof(Product, ID);
Designation.Name = "Designation";
Designation.Shift = offsetof(Product, Designation);
}
ProductSchema& ProductSchema::Default()
{
static ProductSchema instance_;
return instance_;
}
int main()
{
for (int i = 0; i < 10000; i++)
{
Product p;
int* pID = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(&p) + ProductSchema::Default().ID.Shift);
*pID = i;
}
}
Online Demo
Related
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.
I have a public class in which I create an array, this array takes its size from the constructor and needs to be used in other functions (including int main). Therefore the variable must be public. my code looks something along these lines:
class myclass {
public:
int parameter1;
int parameter2;
myclass(int p, int p2) {
parameter1 = p;
parameter2 = p2;
}
void makeArray() {
int array[parameter1][parameter2]; //I want this array to be public as the next method needs access to it
}
void otherFunction() {
array[1][2] = 5; //just an example of what i need to do
}
}
Look up how to use pointers and dynamic memory..
To do what you want would be something like:
class myclass {
public:
int parameter1;
int parameter2;
int **a;
myclass(int p, int p2) {
parameter1 = p;
parameter2 = p2;
a = nullptr;
}
~myclass() {
// TODO: delete "a"
}
void makeArray() {
// TODO: delete "a" if it has already been allocated
a = new *int[parameter1];
for (int i = 0; i < parameter1; ++i) {
a[i] = new int[parameter2];
}
}
void otherFunction() {
// TODO: check that "a" has already been allocated
a[1][2] = 5; //just an example of what i need to do
}
}
You could also allocate the array in the constructor since you have the necessary information being passed in already.
This is more optimized way to do the same thing:
class myclass {
public:
int parameter1;
int parameter2;
int *array;
myclass(int p1, int p2) {
parameter1 = p1;
parameter2 = p2;
}
void makeArray() {
array = new int[parameter1*parameter2];
}
void otherFunction() {
// ary[i][j] is then rewritten as ary[i*sizeY+j]
array[1*parameter2+2] = 5;
}
};
int main()
{
int sizeX = 5;
int sizeY = 5;
myclass m1(sizeX,sizeY);
m1.makeArray();
m1.otherFunction();
cout << m1.array[1*sizeY+2] << endl;
return 0;
}
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.
I have two very similar looking functions, but one creates memory leaks and I do not understand why.
Hasher::~Hasher()
{
clearTable(table); //IF I CHOOSE THIS, I HAVE MEMORY LEAKS
clearTable(); //IF I CHOOSE THIS, THERE ARE NO MEMORY LEAKS
}
void Hasher::clearTable()
{
for (uint i = 0; i < size; ++i)
if (table[i])
clearWord(table[i]);//You can assume this cleans the linked list
}
void Hasher::clearTable(vector<Word *> &t)
{
for (uint i = 0; i < t.size(); ++i)
if (t[i])
clearWord(t[i]);//You can assume this cleans the linked list
}
void clearWord(Word *word)
{
if (word->next)
clearWord(word->next);
delete word;
}
Where the private variables are:
vector<Word *> table;
unsigned int size; // ==table.size()
where:
struct Word{
std::string name;
std::vector<Entry> entries;
Word *next;
Word(std::string a, Entry b) {
name = a; next = NULL;
entries.push_back(b);
};
};
and going further (just in case it helps):
struct Entry{
std::string fullName;
std::vector<Location> loc;
Entry(std::string a, std::vector<Location> b){
fullName = a;
loc = b;
};
Entry(const Entry &a){
fullName = a.fullName;
loc.push_back(a.loc[0]);
};
};
and a little bit more (I don't think this code matters though)
struct Location{
uint file, line;
DirNode * dir;
Location(uint a, uint b, DirNode *c){
file = a;
line = b;
dir = c;
};
Location(const Location &a){
file = a.file;
line = a.line;
dir = a.dir;
};
};
I have to do a program for college.
I have 3 classes already declared in the statement of the problem.
First class:
class piesa_a{
protected:
int id;
char *tip;
int pret;
};
Second class:
class piesa_b:public piesa_a
{
private:
float lungime;
bool bw;
};
Third class:
class piesa_c:public piesa_a
{
private:
int nr;
piesa_b *buf;
};
In main I need to create an array in which to store items such piesa_a, piesa_b, piesa_c. Then I have to sort items by price.
I have this code so far: http://pastebin.com/nx2FGSfe
The program is incomplete because it does not displays each item in the array.
I got stuck here. But if you display the array's elements when they are outside of it, it works.
SHORT: I have an error on line 143 and I want to solve it.
main.cpp:143:18: error: request for member ‘afisare’ in ‘*(v + ((unsigned int)(((unsigned int)i) * 4u)))’, which is of non-class type ‘piesa_a*’
The code is here:
#include <cstdlib>
#include<iostream>
#include<string.h>
using namespace std;
class piesa_a{
protected:
int id;
char *tip;
int pret;
public:
piesa_a()
{
id = 0;
tip = new char[1];
pret = 0;
}
piesa_a(int aidi, char *typ, int pretz)
{
id = aidi;
tip = new char[strlen(typ)+1];
strcpy(tip,typ);
pret = pretz;
}
piesa_a&operator =(piesa_a alta)
{
id = alta.id;
tip = new char[strlen(alta.tip)+1];
strcpy(tip,alta.tip);
pret = alta.pret;
return *this;
}
virtual void afisare()
{
cout<<"\n Piesa A: "<<id<<" "<<tip<<" "<<pret;
}
};
class piesa_b:public piesa_a
{
private:
float lungime;
bool bw;
public:
piesa_b():piesa_a(){lungime = 0;bw = 0;}
piesa_b(float lg,bool bl, int aid, char *tipi, int pretzz):piesa_a(aid,tipi,pretzz)
{
lungime = lg;
bw = bl;
}
piesa_b&operator =(piesa_b &c)
{
id = c.id;
tip = new char[strlen(c.tip)+1];
strcpy(tip,c.tip);
pret = c.pret;
lungime = c.lungime;
bw = c.bw;
return *this;
}
void afisare()
{
piesa_a::afisare();
cout<<"impreuna cu piesa B: "<<lungime<<" "<<bw<<"\n";
}
};
class piesa_c:public piesa_a
{
private:
int nr;
piesa_b *buf;
public:
piesa_c():piesa_a(){nr=0; buf = new piesa_b[nr];}
piesa_c(int n, piesa_b *bu,int aid, char *tipi, int pretzz):piesa_a(aid,tipi,pretzz)
{
nr = n;
buf = new piesa_b[nr];
for(int i=0;i<nr;i++)
buf[i]= bu[i];
}
piesa_c&operator =(piesa_c &alta)
{
id = alta.id;
tip = new char[strlen(alta.tip)+1];
strcpy(tip,alta.tip);
pret = alta.pret;
nr = alta.nr;
for(int i=0;i<alta.nr;i++)
buf[i] = alta.buf[i];
}
void afisare()
{
for(int i=0;i<nr;i++)
buf[i].afisare();
}
};
int main(int argc, char** argv) {
piesa_b *H;
H = new piesa_b[2];
piesa_a A(4,"TIPA",120);
piesa_b B(100,1,3,"TIPA",120);
H[0]=B;
H[1]=B;
piesa_c C(2, H,14,"TIPC",20);
piesa_a** v = new piesa_a*[3];
v[0] = &A;
v[1] = &B;
v[2] = &C;
for(int i=0;i<3;i++)
v[i].afisare();
return 0;
}
What's wrong?
In C++ (and current C), casts are almost always a sign that the programmer didn't know how to use the language as it is supposed to be used. If you need an array of 3 types of data, the cleanest solution is an array of objects of a class that is base to the 3. And if you want to display each item differently, you'll want to overload the << operator, so you just iterate over the array and go << on each item. Sorted by price means that the class includes a price field, and you use the sort from the standard template library, passing a comparison operation that just compares prices.