How to pass child object in the method - c++

I am parsing the child object to a method but my child data is lost. Please tell how to parse the object without loosing its data.
class A
{
int size;
std::string name;
public:
A(const std::string &name, int &size){}
virtual B *C();
}
function D()
{
int size = 10;
std::string name = "name";
return new A(name , size);
}
B *A::C(){
\\here I need name and size
}
Write now the value of size it give is 0 instead of 10 and for name it give segmentation fault
Thanks 4 the help in advance
UPDATE 1
the abstract of my code
class PrototypeAST
{
int size;
std::string FnName;
std::vector<std::string> ArgNames;
public:
PrototypeAST(const std::string &fnName, const std::vector<std::string> &argNames, int &size)
: FnName(fnName), ArgNames(argNames) {}
Function *Codegen();
void CreateArgumentAllocas(Function *F);
};
static PrototypeAST *ParsePrototype() {
int size;
std::string FnName = IdentifierStr;
getNextToken();//eat id1
std::vector<std::string> ArgNames;
if(CurTok != ')' )
{
getNextToken(); //eat int
ArgNames.push_back(IdentifierStr);
getNextToken();// eat id
while (CurTok == ',')
{
getNextToken(); //eat ,
getNextToken(); //eat int
ArgNames.push_back(IdentifierStr);
getNextToken();// eat id
}
}
// success.
getNextToken(); // eat ')'.
size = ArgNames.size();
return new PrototypeAST(FnName, ArgNames, size);
}
Function *PrototypeAST::Codegen() {
printf("\nI am in prototypeAST function\n");
// Make the function type: double(double,double) etc.
std::vector<Type*> Doubles(size,
Type::getInt1Ty(getGlobalContext()));
printf("\nI am in prototypeAST function's 1\n");
FunctionType *FT;
if(isFunInt)
FT = FunctionType::get(Type::getInt1Ty(getGlobalContext()),
Doubles, false);
else if(isFunVoid)
FT = FunctionType::get(Type::getInt1Ty(getGlobalContext()),
Doubles, false);
printf("\nI am in prototypeAST function's 2\n");
Function *F = Function::Create(FT, Function::ExternalLinkage, FnName, TheModule);
printf("\nI am in prototypeAST function's 3\n");
// If F conflicted, there was already something named 'Name'. If it has a
// body, don't allow redefinition or reextern.
if (F->getName() != FnName) {
// Delete the one we just made and get the existing one.
F->eraseFromParent();
F = TheModule->getFunction(FnName);
}
// Set names for all arguments.
unsigned Idx = 0;
for (Function::arg_iterator AI = F->arg_begin(); Idx != ArgNames.size();
++AI, ++Idx) {
AI->setName(ArgNames[Idx]);
}
printf("\nI am in prototypeAST function\n");
return F;
}

As others have pointed out in the comments, you should have looked at the empty constructor. You are not setting the values of the data members in the constructor. That is why the error.
PS: Do familiarize with Stack Overflow question checklist. Happy learning.

I have got what you wanna do. Here is the way to do it.
The empty constructor was making the problem. You can initialize your parameter with the value return by the function in following manner.
class A
{
int Size;
std::string Name;
public:
A(const std::string &name, int &size):Name(name), Size(size) {}
virtual B *C();
}
A *D()
{
int size = 10;
std::string name = "name";
return new A(name , size);
}
B *A::C(){
\\here I need name and size
}

Related

the code doesn't display and doesn't run either

Below is a program that has class definitions for Item, Customer and Sales. The main simply creates object object of each class and test its member functions. Modify the main program such that it provides a menu driven interface where user can create objects of Item, Customer and a complete a sales transaction with the sales object.The program should also have an option for display the records of items,customers and sales.To make your program more useful,include file handling such that when objects are created for Items,Customers and Transaction,the user will be prompted to save the recordon the file or not.
here's the code it's not displaying anything pleasee help i'm running it by Dev c++
#include <conio.h>
#include <iostream>
#include <string.h>
using namespace std;
class Item {
int itemCode;
private:
double price;
double discount;
protected:
int qtyOnStock;
char *name;
public:
Item() {
itemCode = 0;
strcpy(name, "UNKNOWN");
price = 0;
discount = 0;
qtyOnStock = 100;
}
void setItemCode(int c) { itemCode = c; }
int getItemCode() { return itemCode; }
double getPrice() { return price; }
void setPrice(double p) { price = p; }
void setDiscount(double d) { discount = d; }
double getDiscount(double d) { return ((d < 20 ? d : 20) / 100 * price); }
void setName(char *n) { name = n; }
char *getName() { return name; }
void setQtyOnStock(int q) { qtyOnStock = q; }
int getQtyOnStock() { return qtyOnStock; }
};
class Customer {
private:
int id;
char *name;
char *contactNo;
int type;
public:
Customer() {
id = 0;
strcpy(contactNo, "No Num");
strcpy(name, "No Name");
type = 0;
}
void setId(int newId) { id = newId; }
int getId() { return id; }
void setName(char *n) { strcpy(name, n); }
char *getName() { return name; }
void setContactNo(char *c) { strcpy(contactNo, c); }
char *getContactNo() { return name; }
};
class Sales {
private:
Item item;
Customer cust;
char *date;
int qtySold;
public:
Sales() { date = "mm-dd-yyyy"; }
void setItem(Item newItem) { item = newItem; }
Item getItem() { return item; }
void setCustomer(Customer newCust) { cust = newCust; }
Customer getCustomer() { return cust; }
void setDate(char *newDate) { strcpy(date, newDate); }
char *getDate() { return date; }
void setQtySold(int newQty) { qtySold = newQty; }
int getQtySold() { return qtySold; }
};
int main() {
Item item1;
Customer cust1;
Sales sales1;
item1.setItemCode(143);
item1.setName("Ballpen");
item1.setPrice(12.5);
item1.setQtyOnStock(250);
cust1.setId(123);
cust1.setName("Juan dela Cruz");
sales1.setItem(item1);
sales1.setCustomer(cust1);
sales1.setDate("10-27-2018");
sales1.setQtySold(98);
item1.setQtyOnStock(item1.getQtyOnStock() - sales1.getQtySold());
system("cls");
cout << sales1.getItem().getName() << endl << item1.getQtyOnStock();
getch();
return 0;
}
The main and biggest proble is that you do C-style string handling with char* and even that in a wrong way.
If you would enable all warning in your compiler, it would already tell you the problems. My VS2019 gives 15 errors, 1 warning and 7 messages, when I try to compile your code. Please see:
So, the main problem is that you are using char* that are not initialzed, meaning they point to somehwere, and that you do not allocate memory to store your strings.
So all your strcpy functions will fail and probably crash your system. Also the assignments to a char* will fail in most cases.
You will overwrite some random memory.
All this can be immediately fixed, without big problems, if you would use std::string instead of char*. Because char* are that error prone, C++ introduced the std::string, so, please use it.
Sometimes you have C++ teachers that want you to use char*. Those teachers should be fired. But if you really need to use char*. Then you must allocate memory, before coping data.
Let us assume that you have a string "myName" and you want to copy that.
char* name{};
name = new char[strlen(myName)+1]; // +1 for the trailing '\0'
strcpy(name, myName);
// ...
// ...
// Do stuff
// ...
// ...
delete [] name; // Release memory at the end
But as said. Simply use std::string
Your program as is, cannot work. You need a major refactoring.
In your Item class:
protected:
int qtyOnStock;
char *name;
public:
Item() {
itemCode = 0;
strcpy(name, "UNKNOWN");
price = 0;
discount = 0;
qtyOnStock = 100;
}
name is an unitialized char pointer so copying to it will result in UB.
change char* name to std::string name, replace strcpy(...) name = "UNKNOWN".
Normally though you initialize member variables like this:
Item()
: itemCode(0), itemCode(0), name("UNKNOWN"), price(0), discount(0), qtyOnStrock(100)
{}
a newer compiler lets you initialize in other ways like when declared e.g.:
protected:
int qtyOnStock{100};
std::string name{"UNKNOWN"};
...

Arduino split char* based on delimiter to value

thanks for your time, so I have a Char* from mqtt
I want to break this down into 3 seperate values
Char* mqttvalue
//Input Would be like the below for example.
mqttvalue = (255,200,230);
// I would like to split the values into the below.
int 1 = 255
int 2 = 200
int 3 = 230
I've tried strtok with no luck. probably something really dumb but some guidance would help.
Thank you
Edit, what I tried.
//Dummy Value for testing
Split("255,240,230");
//Split Value
void Split(char* e) {
String v[3];
char *p;
int i = 0;
p = strtok(e, ",");
while(p && i < 3)
{
v[i] = p;
p = strtok(NULL, ",");
Serial.println(p);
++i;
};
Serial.println(v[0]);
Serial.println(v[1]);
Serial.println(v[2]);
}
Updated the code to the below from a string to char* its all now working.
//Split Value
void Split(char* e) {
char* v[3];
char *p;
int i = 0;
p = strtok(rgb, ",");
while(p && i < 3)
{
v[i] = p;
p = strtok(NULL, ",");
i++;
};
Serial.println(v[0]);
Serial.println(v[1]);
Serial.println(v[2]);
};
As this is quite often asked question and I'd propose more like using wrapper class inheriting Stream interface on C string (and it can be initialized from Arduino String object too).
However usage with Arduino String class is tricky as the original String shouldn't be altered during usage of StringStream, but it's possible to reinitialize it again. Using rvalue (String literal, passed into the class) is forbidden by using non const reference as the parameter of setData method and constructor.
However it's not tested much, so there might be some mistakes. The copy/move constructor and assigment is ommited (and it shouldn't be :D), also using operator=(String&) and operator=(const char*) would be more intuitive interface for it.
class StringStream : public Stream
{
public:
StringStream()
{
setTimeout(1);
}
StringStream(const char * str)
{
setData(str);
}
StringStream(const char * begin, const char * end)
{
setData(begin, end);
}
explicit StringStream(String & view) // cannot be String literal (rvalue) and it gets invalidated if you change original String
{
setData(view);
}
////////////////////////////////////
inline void setData(const char * begin, const char * end)
{
m_start = begin;
m_end = end;
setTimeout(1);
}
inline void setData(const char * begin)
{
setData(begin, begin + strlen(begin));
}
inline void setData(String & view)
{
setData(view.c_str(), m_start + view.length());
}
//////////////////////////////////
// Stream Interface:
virtual int available() override
{
return m_end - m_start;
}
virtual int read() override
{
if (m_start < m_end)
{
return *(m_start++);
}
return -1;
}
virtual int peek() override
{
if (m_start < m_end)
{
return *m_start;
}
return -1;
}
virtual size_t write(uint8_t) override {
return 0;
}
protected:
const char * m_start{0};
const char * m_end{0};
};
And the test program would be like:
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.println("Output:");
StringStream test{" 144, 7899, -5478"};
Serial.println(test.parseInt());
Serial.println(test.parseInt());
Serial.println(test.parseInt());
test.setData("1 2");
Serial.println(test.parseInt());
Serial.println(test.parseInt());
delay(2000);
}

C++ getter method for private variable not working properly(Only have Java experience)

My header file
class Roster {
private:
Degree degree = NETWORK;
int addFlag = 0;
Student* classRosterArray[5] = { nullptr, nullptr, nullptr, nullptr, nullptr };
public:
void add(string studentID, string firstName, string lastName, string emailAddress,
int age, int daysToComplete1, int daysToComplete2, int daysToComplete3, Degree degreeProgram);
void remove(string studentId);
void printAll();
void printByDegreeProgram(int degreeProgram);
void printDaysInCourse(string studentId);
void printInvalidEmails();
Student* getClassRosterArray();
~Roster();
};
My getter method in CCP file
Student* Roster::getClassRosterArray() {
return *classRosterArray;
}
My main() in CCP
for (int k = 0; k < 5; k++) {
cout << "Student ID :: " << roster.getClassRosterArray()[k].getStudentId() << endl;
}
And it only takes out the first Student object, for the second index in array is empty....
Pleaese help! it is my first trying C++.!!
I will propose this change :
Student* getClassRosterArray( int ) ;
...
Student* Roster::getClassRosterArray(int id) {
return classRosterArray[id];
}
...
for (int k = 0; k < 5; k++) {
cout << "Student ID :: " << roster.getClassRosterArray(k)->getStudentId() << endl;
}
To retrieve the member without losing its size information, you might do
class Roster {
private:
Student* classRosterArray[5] = { nullptr, nullptr, nullptr, nullptr, nullptr };
// ...
public:
auto getClassRosterArray() -> Student* (&)[5] { return classRosterArray;}
// ...
};
Ugly syntax :/
std::array<Student*, 5> has more regular syntax:
class Roster {
private:
std::array<Student*, 5> classRosterArray{{ nullptr, nullptr, nullptr, nullptr, nullptr }};
// ...
public:
std::array<Student*, 5>& getClassRosterArray() { return classRosterArray;}
// ...
};
As Student seems not polymorphic, not using pointer seems even simpler with std::vector:
class Roster {
private:
std::vector<Student> classRosterArray;
// ...
public:
std::vector<Student>& getClassRosterArray() { return classRosterArray;}
// ...
};
You declare an array of Student*, in other words you declare a Student**.
The get method return the a Student* and not a Student** or better a Student*[].
This cause you problem. In other words you return only the first element of the array.

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.

C++ GetName vector of objects

i have this class
class Dados
{
string name;
int valor;
public:
Dados(string n, int v) : name(n), valor(v){};
//~dados();
string GetName(){return name;}
int GetValor(){return valor;}
void SetValor(int x){valor = x;}
}
and this class, which basically reads a file and put the data into a vector:
class FileReader{
vector<Dados> dados;
public:
bool ReadFile(string file) {
dados.empty();
string fnome, ftemp;
int fvalor;
ifstream fich(file);
string linha;
if (fich.is_open())
{
while (fich.peek() != EOF){
getline(fich, linha);
istringstream iss(linha);
//cout << ".";
iss >> fnome;
iss >> ftemp;
iss >> fvalor;
dados.push_back(Dados(fnome,fvalor));
}
fich.close();
return 0;
}
else{
cout << "Ficheiro \""<< file <<"\" nao encontrado!";
return 1;
}
}
int FindOnVector(string fi)
{
int val;
vector<Dados>::const_iterator it;
it = dados.begin();
while (it != dados.end()){
val = it->GetValor();
it++;
}
return val;
}
};
But on class FileReader i need on method for find a name, and return int (valor).
This time he just doing this return value. Not this search a name.
but val = it->GetValor();
Give to me this error on VS 2012:
error C2662: 'Dados::GetValor' : cannot convert 'this' pointer from 'const Dados' to 'Dados &'
someon can me help?
Bests
Make the GetValor method const:
`int GetValor() const {return valor;}`
Declare the getter like this and it will work:
int GetValor() const {return valor;}
The const keyword indicates that calling GetValor does not modify the object.
Not related to your question, but this is wrong:
while (fich.peek() != EOF)
{
// ...
}
You should just have
while (std::getline(fich, linha))
{
// ...
}
To your original question, you need a getter for name that has a const modifier:
string GetName() const
{
return name;
}
The same goes for all your getters if you wish to use them in const functions/iterators.
First of all declare these functions as const
string GetName()const {return name;}
int GetValor() const {return valor;}
Secondly this statement in function ReadFile
dados.empty();
has no any sense. It simply returns true if the vector is empty. I think you meant
dados.clear();
As for searching an element of the vector then it is better to use standard algorithm std::find()or std::find_ifif you will use a lambda expression or a standard predicate . If you will use std::find you need to define operator == for class Dados.
As for your own function that you should decide what it will return in case when nothing was found. Suppose you will return 0. So the function could look the following way
int FindOnVector( const string &fi ) const
{
int val = 0;
for ( const Dados &d : dados )
{
if ( d.GetName() == fi )
{
val = d.GetValor();
break;
}
}
return val;
}