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.!
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 am relatively new to c++ and I have just learned how to use an array in a class, but I can't figure out how to add private members of one class to an array of a different class. I have a base class named collection, and a derived class called wallHangingType. When I try to input the length and width variable from wallHangingType into the array I get the error class collection has no member named 'length' or 'width'. I am required to have length and width in wallHangingType and not move them to the collection class. I would like to know how I would fix this to be able to input the length and width variables into the array.
collection.h
#ifndef COLLECTION_H
#define COLLECTION_H
#include <string>
class collection
{
public:
collection(int = 0, std::string = "NA", std::string = "NA");
std::string getArtistName();
std::string getTitle();
void setTitle(std::string artTitle);
void setArtist(std::string artist);
void setId(int id);
void print() const;
private:
std::string artistName;
std::string title;
int idNum;
};
#endif // COLLECTION_H
wallHangingType.h
#ifndef WALLHANGINGTYPE_H
#define WALLHANGINGTYPE_H
#include "collection.h"
class wallHangingType:public collection
{
public:
wallHangingType();
void addPiece(int id, std::string name, std::string artTitle,int artLength, int artWidth);
void removePiece();
void printArt();
private:
int length;
int width;
collection pieces[100];
int index;
};
#endif // WALLHANGINGTYPE_H
wallHangingType.cpp
#include <iostream>
using namespace std;
wallHangingType::wallHangingType()
{
index = 0;
}
void wallHangingType::addPiece(int id, std::string name, std::string artTitle,int artLength, int artWidth)
{
pieces[index].setId(id);
pieces[index].setArtist(name);
pieces[index].setTitle(artTitle);
pieces[index].length = artLength; //ERROR
pieces[index].width = artWidth; //ERROR
}
I'm new to C++ and stuck on a problem. I want class Admin to be able to create new objects of the Student class and add the objects to an array that contains all students' info. How can I do that in the Admin class?
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Student
{
public:
int SSN_LENGTH = 9, MIN_NAME_LEN = 1, MAX_NAME_LEN = 40;
string DEFAULT_NAME = "no name", DEFAULT_SSN = "000000000";
private:
string studentName, SSN;
public:
// constructor declarations
Student();
Student( string studentName, string SSN);
// Accessors
string getSSN(){ return SSN; }
string getStudentName(){ return studentName; }
// Mutators
bool setSSN(string SSN);
bool setStudentName(string studentName);
};
class Admin
{
private:
static const int Student_MAX_SIZE = 100000;
public:
bool addStudent (string studentName, string SSN);
};
How can I do that in the Admin class?
Use std::vector, illustrated by the code below:
#include <vector>
//...
class Admin
{
private:
static const std::size_t Student_MAX_SIZE = 100000;
std::vector<Student> vStudent;
public:
bool addStudent (string studentName, string SSN)
{
if ( vStudent.size() < Student_MAX_SIZE )
{
vStudent.push_back(Student(studentName, SSN));
return true;
}
return false;
}
};
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.
I already asked about my Problem, now I'm on the next Step. In the code below I have the Problem, that I always have to make the EventHandler (Server::HandleMessage) static. But I need to have it non static to access other Variables in the Server class from within the Handler.
How can I achieve this?
Here my Code:
#include <iostream>
#include <functional>
using namespace std;
class Client{
public:
struct MessageReceiveArgs {
MessageReceiveArgs(int ID, const std::string& Text) : ID(ID), Text(Text) {}
int ID;
std::string Text;
};
std::function<void(MessageReceiveArgs)> onMessageReceive;
Client(){}
void FireEvent(){
this->onMessageReceive(MessageReceiveArgs(16, "SomeText"));
}
};
class Server{
public:
int i;
Server(){
this->client.onMessageReceive = &Server::HandleMessage;
this->i = 5;
}
void FireEvent(){
this->client.FireEvent();
}
Client client;
static void HandleMessage(Client::MessageReceiveArgs args) {
std::cout<<"ID "<<args.ID<<": "<<" "<<args.Text<<std::endl;
//need it non static
//std::cout<<"I: "<<this->i<<std::endl;
}
};
int main() {
Server sv = Server();
sv.FireEvent();
}
As mentioned in my earlier Post, i'm new to Standard C++ (Unix).
I'm fairly sure this is what you're after. You need to bind the implicit this explicitly when invoking a pointer-to-member through std::function in the fashion you seem to desire.
#include <iostream>
#include <functional>
using namespace std;
class Client{
public:
struct MessageReceiveArgs
{
MessageReceiveArgs(int ID, const std::string& Text)
: ID(ID), Text(Text) {}
int ID;
std::string Text;
};
Client(){}
void FireEvent()
{
this->onMessageReceive(MessageReceiveArgs(16, "SomeText"));
}
std::function<void(MessageReceiveArgs)> onMessageReceive;
};
class Server
{
public:
int i;
Server()
{
this->client.onMessageReceive
= std::bind(&Server::HandleMessage, this, std::placeholders::_1);
this->i = 5;
}
void FireEvent()
{
this->client.FireEvent();
}
Client client;
void HandleMessage(Client::MessageReceiveArgs args)
{
std::cout<<"ID "<<args.ID<<": "<<" "<<args.Text<<std::endl;
}
};
int main()
{
Server sv = Server();
sv.FireEvent();
}
Output
ID 16: SomeText