was in this for few hours now and I cannot seem to find the right way to do this. I am creating a vector that will be populated with structs but I could not make it to work. I have tried making a struct and put the struct from the object in there but received an error. Anyways this is my work, I am really new into this so I hope you guys could help me out.
main.cpp
#include <iostream>
#include "CBank.h"
int main()
{
CBank bank;
struct account = bank.account;
bank.account.name = "Alpha Omega";
bank.account.money = 15635.23;
bank.account.pin = 3241;
bank.add.push_back(account);
return 0;
}
CBank.h
#ifndef CBANK_H
#define CBANK_H
#include <iostream>
#include <vector>
class CBank
{
public:
CBank();
private:
struct account { std::string name;
float money;
short pin;
};
std::vector<account> add;
};
#endif // CBANK_H
CBank.cpp
#include "CBank.h"
CBank::CBank()
{
//ctor
}
The problem is that you define a type (account) in the class. account is a type so you should not declare it in the class :
struct account { std::string name;
float money;
short pin;
};
and then, the class becomes :
class CBank
{
public:
CBank();
account acc;
std::vector<account> add;
};
and the main :
int main()
{
CBank bank;
bank.acc.name = "Alpha Omega";
bank.acc.money = 15635.23;
bank.acc.pin = 3241;
bank.add.push_back(bank.acc);
return 0;
}
Your struct account and add vector are private members of CBank. To access them you need to make them public like your class constructor is.
Related
I need to get in a vector the names of some cities as soon as they are created... In order to accomplish that I created a static vector for the class City, however when I try to compile my code I get the error
error: lvalue required as unary '&' operand
this->cities.push_back(&this);
^~~~
What am I doing wrong?
My code is the following...
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
class City
{
private:
string name;
static vector<City *> cities;
public:
string getName() { return name; }
City(string name) : name{name}
{
this->cities.push_back(&this);
};
~City(){};
} hongKong{"Hong Kong"}, bangkok{"Bangkok"}, macau{"Macau"}, singapura{"Singapura"}, londres{"Londres"}, paris{"Paris"}, dubai{"Dubai"}, delhi{"Delhi"}, istambul{"Istambul"}, kuala{"Kuala"}, lumpur{"Lumpur"}, novaIorque{"Nova Iorque"}, antalya{"Antalya"}, mumbai{"Mumbai"}, shenzen{"Shenzen"}, phuket{"Phuket"};
int main()
{
}
this is already a City* pointer, so drop the & from &this.
Also, don't forget to actually define the static vector object.
Also, you should account for the class' copy/move constructors and destructor, to make sure you don't miss adding pointers, or leave behind dangling pointers.
Try this:
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
class City
{
private:
string name;
static vector<City *> cities;
public:
string getName() { return name; }
City(string name) : name{name}
{
cities.push_back(this);
}
City(const City &src) : name{src.name}
{
cities.push_back(this);
}
City(City &&src) : name{std::move(src.name)}
{
cities.push_back(this);
}
~City()
{
cities.erase(std::find(cities.begin(), cities.end(), this));
}
};
vector<City *> City::cities;
City hongKong{"Hong Kong"}, bangkok{"Bangkok"}, macau{"Macau"}, singapura{"Singapura"}, londres{"Londres"}, paris{"Paris"}, dubai{"Dubai"}, delhi{"Delhi"}, istambul{"Istambul"}, kuala{"Kuala"}, lumpur{"Lumpur"}, novaIorque{"Nova Iorque"}, antalya{"Antalya"}, mumbai{"Mumbai"}, shenzen{"Shenzen"}, phuket{"Phuket"};
int main()
{
}
I'm doing a program that just have to print value of the variables, i think the first class is working, the 'm_valor' is printed like i want , but the second class should be printing 'm_valor + m_valorAdicional', but it is printing just the value of 'm_valorAdicional':
#ifndef INGRESSO_H
#define INGRESSO_H
#include <iostream>
using namespace std;
class Ingresso
{
protected:
float m_valor;
public:
Ingresso(): m_valor(0){};
Ingresso(float valor): m_valor(valor){};
~Ingresso(){};
float getValor() const {return m_valor; };
};
class IngressoVip : public Ingresso
{
private:
float m_valorAdicional;
public:
IngressoVip(): m_valorAdicional(0){};
IngressoVip(float valor): m_valorAdicional(valor){};
~IngressoVip(){};
float getValor(){return m_valorAdicional +=m_valor;};
};
#endif
main.cpp:
#include "Ingresso.hpp"
int main()
{
Ingresso a(10);
IngressoVip b(5);
out<<"valor Ingresso: "<<a.getValor()<<endl;
cout<<"valor IngressoVip: "<<b.getValor()<<endl;
return 0;
}
I think this should be easy, but i just don't know what i have to do to work like i want.
You should use +, not +=. What += does here in this line:
return m_valorAdicional +=m_valor;
is it adds the value of m_valor to m_valorAdicional, changing the value of m_valorAdicional, and then returning this new value. If you don't want to change the values of the variables use +.
Here is my base class:
#include <string>
#include "DataStruct.h"
#include <vector>
#include <mysqlx/xdevapi.h>
#include <iostream>
#include <memory>
namespace Vibranium {
using namespace mysqlx;
class MySQLTable {
public:
MySQLTable();
virtual ~MySQLTable() = default;
int Index;
std::string tableName;
DataStruct dataStruct;
std::vector<std::unique_ptr<DataStruct>> Data;
Table getTable(Session& conn) const;
RowResult getAll(Session& conn) const;
virtual void LoadTable(RowResult& res) {}
};
}
#endif //VIBRANIUM_CORE_MYSQLTABLE_H
Which is representing all MySQL tables i might have. Take a look at Data vector of types DataStruct. I use DataStruct as a base struct because all tables will have different structure.
Here is base DataStruct struct:
namespace Vibranium{
struct DataStruct{};
}
Than I define my first mysql tablle Accounts:
#include <string>
#include "Database/DataStruct.h"
#include "Database/MySQLTable.h"
namespace Vibranium{
using namespace std;
struct AccountsStruct : DataStruct{
int id;
std::string email;
std::string warTag;
int state;
std::string name;
std::string lastname;
std::string country;
int dob_month;
int dob_day;
int dob_year;
double balance;
std::string created_at;
std::string updated_at;
int account_role;
int rank;
int playerRole;
};
class Accounts : public MySQLTable{
public:
Accounts() = default;
void LoadTable(RowResult& res) override;
};
}
As you can see inside I have defined AccountsStruct as child of DataStruct.
Here is how I implement LoadTable:
#include "Accounts.h"
using namespace Vibranium;
void Vibranium::Accounts::LoadTable(RowResult &res) {
std::vector<AccountsStruct> accounts;
AccountsStruct accountsStruct;
for (Row row : res.fetchAll()){
accountsStruct.id = row[0].get<int>();
accountsStruct.email = row[1].get<std::string>();
accountsStruct.warTag = row[2].get<std::string>();
accountsStruct.state = row[4].get<int>();
accountsStruct.name = row[5].get<std::string>();
accountsStruct.lastname = row[6].get<std::string>();
accountsStruct.country = row[7].get<std::string>();
accountsStruct.dob_month = row[8].get<int>();
accountsStruct.dob_day = row[9].get<int>();
accountsStruct.dob_year = row[10].get<int>();
accountsStruct.balance = row[11].get<double>();
accountsStruct.created_at = row[12].get<std::string>();
accountsStruct.updated_at = row[13].get<std::string>();
accountsStruct.account_role = row[15].get<int>();
accountsStruct.rank = row[16].get<int>();
accountsStruct.playerRole = row[17].get<int>();
accounts.push_back(accountsStruct);
}
}
As Accounts is child of MySQLTable
I would like to add all the data from std::vector<AccountsStruct> accounts into Data vector inherited from MySQlTable.
Also after that I would like to cycle thru the vector Data as it
is of type Accounts instead of MySQLTable class. However I don't
know how can I achieve those two things.
Is it possible and how?
I would drop the type DataStruct, and make MySqlTable a template.
#include <string>
#include <vector>
#include <mysqlx/xdevapi.h>
#include <memory>
namespace Vibranium {
using mysqlx::Table;
using mysqlx::RowResult;
using mysqlx::Session;
class MySQLTableBase {
public:
MySQLTableBase();
virtual ~MySQLTableBase() = default;
Table getTable(Session& conn) const;
RowResult getAll(Session& conn) const;
int Index;
std::string tableName;
};
template <typename T>
class MySQLTable : public MySQLTableBase {
public:
virtual void LoadTable(RowResult& res) = 0;
T dataStruct; // What is this?
std::vector<T> Data; // You don't need vector of pointers
};
}
Then you define Account and Accounts as
#include <string>
#include "Database/MySQLTable.h"
namespace Vibranium{
struct Account{
int id;
std::string email;
std::string warTag;
int state;
std::string name;
std::string lastname;
std::string country;
int dob_month;
int dob_day;
int dob_year;
double balance;
std::string created_at;
std::string updated_at;
int account_role;
int rank;
int playerRole;
};
class Accounts : public MySQLTable<Account>{
public:
Accounts() = default;
void LoadTable(RowResult& res) override;
};
}
So, have fun with C++!
You don't have a vector in MySQLTable with name "Data". You have method (Data) returning vector of ... To implement your request you should create method (for example) void SetData(...).
You can't. You can cycle through vector of Data and cast (for example static_cast, or other) each element from Data to AccountStruct. WARNING! Wrong cast operation may cause undefined behavior, crashes, etc.!
I have 2 classes. Since Doctor will be considered as Employee, I should be using Employee class functions in Doctor class. Only extra thing that Doctor class has is TITLE. Basically, What I tried is I wanted to send value to Doctor's constructor,set title then send remained value to Employee's class ;however, I could not. This is what I have done so far,
employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
class Employee {
private:
int ID;
char *firstname;
char *lastname;
int telno;
char *adress;
char *mail;
int salary;
public:
Employee();
Employee(int,char *,char*,int,char*,char*,int);
char* getfmame();
char* getlname();
char* getadress();
char* getmail();
int getID();
int gettel();
int getsalary();
void printall();
};
#endif
Employee.cpp
#include <iostream>
#include "employee.h"
using namespace std;
Employee::Employee() {
firstname = "Empty";
ID=0;
firstname="Empty";
lastname="Empty";
telno=0;
adress="Empty";
mail="Empty";
salary=0;
}
Employee::Employee(int id,char * first,char* last,int tell,char* adres,char* email,int salar){
ID=id;
firstname=first;
lastname=last;
telno=tell;
adress=adres;
mail=email;
salary=salar;
}
char* Employee::getfmame(){ return firstname; }
char* Employee::getlname(){ return lastname; }
char* Employee::getadress(){ return adress; }
char* Employee::getmail(){ return mail; }
int Employee::getID(){ return ID; }
int Employee::gettel(){ return telno; }
int Employee::getsalary(){ return salary; }
void Employee::printall(){
cout<<endl<<"EMLOYEE INFORMATION"<<endl<<"------------------"<<endl;
cout<<endl<<"ID :"<<ID<<endl<<"FIRST NAME: "<< firstname <<endl<<"LAST NAME: "<< lastname << endl << "TELEPHONE NUMBER: "<<telno<<endl<<"ADRESS: "<<adress<<endl<<"MAIL: "<<mail<<endl<<"SALARY: "<<salary<<endl;
}
Doctor.h
#ifndef DOCTOR_H
#define DOCTOR_H
#include "Employee.h"
using namespace std;
class Doctor :Employee {
public:
enum title {Intern=0,Practitioner=1,Assistant=2,Specialist=3,Docent=4,Professor=5,None=6};
Doctor();
Doctor(title a,int id,char * first,char* last,int tell,char* adres,char* email,int salar);
};
#endif
Doctor.cpp
#include <iostream>
#include "Doctor.h"
#include "Employee.h"
using namespace std;
Doctor::Doctor() {
title tit = None ;
}
Doctor::Doctor(title a,int id,char * first,char* last,int tell,char* adres,char* email,int salar) {
title tit=a;
Employee(id,first,last, tell,adres,email,salar);
printall();
cout<<"typed";
}
Main.cpp
#include <iostream>
#include "employee.h"
#include "doctor.h"
using namespace std;
int main(){
Doctor a=Doctor(Doctor::None,12,"a","b",0550550505,"8424 str nu:5","#hotmail",5000);
return 0;
}
Subclass construction in C++ works so that the base class object must be constructed when the subclass' constructor body is executed:
class A {
/* etc. etc. */
public:
void do_stuff();
};
class B : public A {
B() {
// at this point, an A has already been constructed!
A::do_stuff();
}
};
Note that in this example, since we haven't chosen an explicit constructor for the A instance, the default constructor, A::A(), will be used; and if that constructor is unavailable - we get a compilation error. The fact that a constructor for A has been called is what allows us to then use methods of class A - like A::do_stuff() in the example above.
But - how can we specify a different constructor before the body of the B constructor? Or in your case, how can we use the appropriate constructor for Employee before the body of the Doctor constructor?
The answer was suggested by #user4581301: You need to use an member initializer list. Initializations/constructions on this list are performed before the body, and may include the underlying class. I'll demonstrate with a simplified example. Let's suppose an Employee only has an id and a Doctor only has an additional title.
class Employee {
protected:
int id_;
public:
Employee(int id) : id_(id) { };
int id() const { return id_; }
};
class Doctor : public Employee {
protected:
std::string title_;
public:
Doctor(int id, std::string title) : Employee(id), title_(title) { };
const std::string& title() const { return title_; }
};
So, when a Doctor is being constructed, it constructs its underlying Employee instance using the id it got. The constructor body is used for more complex code beyond simple member initializations.
PS:
You might want to initialize the title_ member with std::move(title) rather than just title, see this question for details.
It's confusing when a constructor has more than two or three parameters with compatible types - users are likely to confuse them with each other. You might consider default values for most fields and setting them after construction, or alternatively, using a builder pattern.
address, with two d's, not adress.
Unless you plan on editing char* fields in-place, use const char *.
They way you've written your classes, Doctor methods would not have write acesss to Employee methods; make sure that's what you intended.
I have some other nitpicks but I'll stop now...
Based on my Snack.cpp, Snack header file, MiniVend header file & miniVend.cpp file, I am trying to move my Snack private member - price into my MiniVend.cpp file to generate the amount * price to return a total value of items in my machine. How do I access the price from another class?
Portion of my miniVend.cpp file
double miniVend::valueOfSnacks()
{
return //// I don't know how to get snacks price in here? I need to access snacks & getSnackPrice.
}
miniVend header
#ifndef MINIVEND
#define MINIVEND
#include <string>
#include "VendSlot.h"
#include "Snack.h"
using std::string;
class miniVend
{
public:
miniVend(VendSlot, VendSlot, VendSlot, VendSlot, double); //constructor
int numEmptySlots();
double valueOfSnacks();
//void buySnack(int);
double getMoney();
~miniVend(); //desructor
private:
VendSlot vendslot1; //declare all the vending slots.
VendSlot vendslot2; //declare all the vending slots.
VendSlot vendslot3; //declare all the vending slots.
VendSlot vendslot4; //declare all the vending slots.
double moneyInMachine; //money in the machine
};
#endif // !MINIVEND
Snack.cpp
#include "Snack.h"
#include <iostream>
#include <string>
using std::endl;
using std::string;
using std::cout;
using std::cin;
Snack::Snack() //default constructor
{
nameOfSnack = "bottled water";
snackPrice = 1.75;
numOfCalories = 0;
}
Snack::Snack(string name, double price, int cals)
{
nameOfSnack = name;
snackPrice = price;
numOfCalories = cals;
}
Snack::~Snack()
{
}
string Snack::getNameOfSnack()
{
return nameOfSnack;
}
double Snack::getSnackPrice()
{
return snackPrice;
}
int Snack::getNumOfCalories()
{
return numOfCalories;
}
Snack.h file
#ifndef SNACK_CPP
#define SNACK_CPP
#include <string>
using std::string;
class Snack
{
private:
string nameOfSnack;
double snackPrice;
int numOfCalories;
public:
Snack(); //default constructor
Snack(string name, double price, int cals); //overload constructor
~Snack(); //destructor
//Accessor functions
string getNameOfSnack(); //returns name of snack
double getSnackPrice(); //returns the price of the snack
int getNumOfCalories(); //returns number of calories of snack
};
#endif // !SNACK_CPP
Assuming getSnackPrice() is public, and Snack.h does exist, you should just be able to call
snackObject.getSnackPrice() * ammount
what you need is friend keyword. Define the
friend class className;
I don't really understand why you don't just implement get()? Accessing private data is really bad. You are breaking the encapsulation. But if you really want to know (i.e. you should NOT do it, it is really BAD), then you just return a reference to a private data as shown below
#include <iostream>
class A
{
public:
A(int a) : x(a) {}
int &getPrivateDataBAD() { return x; }
void print() { std::cout << x << std::endl; }
private:
int x;
};
class B
{
public:
void print(int &s) { std::cout << s << std::endl; }
};
int main()
{
A obj(2);
B bObj;
bObj.print( obj.getPrivateDataBAD() );
return 0;
}