I am not sure if my title makes any sense. I am trying to implement a queue class in c++. Below is my q.cpp class so far
#include "q.h"
q::q()
{
for(int i = 0; i < q::QUEUE_SIZE; i++)
{
q::data[i] = '0';
}
q::front = q::rear = -1;
printf(" YEA QUEUE HAS BEEN CREATED ");
}
q* q::createQueue()
{
return new q;
}
Now in my output class (main.cpp), I want to be able to create new queues through the createQueue() function call and returning a handle to the current queue class object
Something like this
q* firstQueue = createQueue();
q* secondQueue = createQueue();
I was thinking my main constructor q() needs to be private and createQueue should act like a factory so my q.h file should be something like below?
#ifndef Q_H
#define Q_H
#include <stdio.h>
class q
{
public:
void destroy_queue(q* currentQueue);
void enque_byte(q* currentQueue,unsigned char b);
unsigned char deque_byte(q* currentQueue);
static q* createQueue();
private:
static const int QUEUE_SIZE = 2048;
unsigned char data[QUEUE_SIZE];
int front, rear;
q();
};
#endif // Q_H
And then how would I be able to do enqueue, dequeue operations by calling
And then do enqueue and dequeue operations on any number of queues like
enqueue(firstQueue,5);
dequeue(firstQueue);
enqueue(secondQueue,10);
..
..
And not use objects to call them like
firstQueue->enqueue(...)
I am slightly confused with the organization of my code. Hope someone could provide an insight on how can I achieve such a structure?
You can just write simple wrappers like
void enqueue(q* obj, int x) {
obj->enqueue(x);
}
All this doesn't make much sense, however; the C++ idiom is to use objects and methods and, unless you are in a case where this idiom doesn't work that well (e.g. multimethods), following it is much easier than fighting against it.
Related
I'm running into a situation where I need to use virtual get and set functions to access members of derived classes. However, as pointed out in the answers of this topic (which is quite similar to my problem by the way), this is a bad practice and may mean that my classes need to be redesigned. The thing is... I'm new to C++ and OOP in general, so I'm not sure how exactly I can write my code in a different way.
If you have the patience, I'll explain my situation: I'm working on a code that can solve two different types of problem (say ProblemX and ProblemY). Depending on the user input, you can solve only problemX, only ProblemY, or both at the same time. If you want to solve only ProblemX, you need only a variable named "memberX". If you want to solve only ProblemY, you need only "memberY". If you want to solve both at the same time, you'll need both "memberX" and "memberY", but the problems will depend on each other, so you can't solve each problem individually. In short, the code would be something like this:
#include <vector>
class Problem
{
public:
double memberX;
double memberY;
};
class MainProblem
{
public:
std::vector<Problem*> problems;
};
int main()
{
bool solveProblemX = true; // This variable will depend on user input
bool solveProblemY = true; // This variable will depend on user input
MainProblem * mainProblem = new MainProblem();
for (int i = 0; i < 10000; i++)
{
Problem * problem = new Problem();
mainProblem->problems.push_back(*problem);
}
if (solveProblemX && solveProblemY)
{
// Solve interconnected problem, using "mainProblem->problem[i]->memberX" and "mainProblem->problem[i]->memberY";
}
else if (solveProblemX)
{
// Solve individual problem, using only "mainProblem->problem[i]->memberX";
}
else if (solveProblemY)
{
// Solve individual problem, using only "mainProblem->problem[i]->memberY";
}
else
{
// throw some exception
}
}
So far so good... the real problem is: although I gave only a small sample of the code, my real program is in fact very memory expensive (I actually have a large set of Problems, and each contains a large set of members). So, in order to reduce memory usage, I had to make some modifications. For example: If the user chooses to solve only problemX, the variable memberY will only be a dead weight, since the program won't need it. And vice versa.
Therefore, I thought in making derived classes for ProblemX and ProblemY individually, each containing their respectives data member. That way, I can assign to the vector of problems only a minor class containing specifically the data I need. And if I need both, I use another derived class named ProblemXandY, which containd both memberX and memberY. This is the code I thought:
#include <vector>
class Problem
{
public:
virtual double getMemberX(){ // Throw some exception};
virtual double getMemberY(){ // Throw some exception};
};
class ProblemX : public Problem
{
private:
double memberX;
public:
double getMemberX(){ return memberX; };
};
class ProblemY : public Problem
{
private:
double memberY;
public:
double getMemberY(){ return memberY; };
};
class ProblemXandY : public ProblemX, public ProblemY
{};
class MainProblem
{
public:
std::vector<Problem*> problems;
};
int main()
{
bool solveProblemX = true; // This variable will depend on user input
bool solveProblemY = true; // This variable will depend on user input
MainProblem * mainProblem = new MainProblem();
for (int i = 0; i < 10000; i++)
{
Problem * problem;
if (solveProblemX && solveProblemY)
problem = new ProblemXandY();
else if (solveProblemX)
problem = new ProblemX();
else if (solveProblemY)
problem = new ProblemY();
else
// throw some exception
mainProblem->problems.push_back(*problem);
}
if (solveProblemX && solveProblemY)
{
for (int i = 0; i < 10000; i++)
{
double memberX = mainProblem->problems[i]->getMemberX();
double memberY = mainProblem->problems[i]->getMemberY();
// Solve interconnected problem, using "memberX" and "memberY"
}
}
else if (solveProblemX)
{
for (int i = 0; i < 10000; i++)
{
double memberX = mainProblem->problems[i]->getMemberX();
// Solve individual problem, using only "memberX";
}
}
else if (solveProblemY)
{
for (int i = 0; i < 10000; i++)
{
double memberY = mainProblem->problems[i]->getMemberY();
// Solve individual problem, using only "memberY";
}
}
else
{
// throw some exception
}
}
My question is regarding the virtual get functions on the class Problem. It feels strange, I agree, since the variables memberX and memberY don't belong to the class Problem. However, without it I wouldn't be able to call mainProblem->problems[i]->getMemberX(), since mainProblem->problems[i] is an object of the base class Problem, instead of the derived classes. As I said, my program is memory expensive. That's why I chose to have a single vector of Problems in the class MainProblem, instead of multiple vectors, one for each derived class. Is there something wrong with my structure here? Should I really redesign it? If so, can you think of an alternative?
Here's my issue, I would like to call the getters/setters of one of my objects, but not directly, I want to do it by using a std::string.
I found this but it won't work on my case I think it is because my function aren't defined in my main method but in my square class. Also my function are not all defined the same way there's void(std::string) std::string() void(int)...
here's an exemple of what a would like to do.
my object square
#include <map>
#include <functional>
#include <string>
class Square{
private:
std::string name;
int width;
float happinessPoint; //extremly important for your square.
public:
void setName(std::string);
void setWidth(int);
void setHappinessPoint(float);
std::string getName()
int getWidth()
float getHappinnessPoint()
}
and my main
#include "Square.h/cpp"
int main(){
Square square = Square("Roger",2,3.5);
// here in my magicalFunction I ask to the users the new values for my square (all in std::string for now)
vector <std::string> newValueForSquare = magicalFunction();
for (unsigned int i=0; i < newValueForSquare.size(), i++){
//here I have a function which tell me if my std::string
// is in fact a float or an int
// and I would like to call each of my setters one by one to
// sets my Square to some value I asked to the user before all that.
// something like that:
// someFunction("setName","Henry")
}
}
I hope i have been clear it's pretty hard to explain something you don't know how to do. If you want me to be more specific tell me and I'll do what I can.
EDIT: What I want to do is to call for example my square.setName() with a str::string without writting this square.setName in my main.
To call functions, based on a string, you have some choices. Before I list the choices, please search the internet for "C++ factory design pattern".
If-else ladder
Lookup table
Map / Associative array
Hash table
There may be other methods, but the above come to mind.
if-else ladder (a.k.a. switch)
The problem with this method is that the switch statement doesn't work with strings nor text literals. So you'll have to suffice with if statements:
if (string == "Roger")
{
Process_Roger();
}
else if (string == "Felicity")
{
Process_Felicity();
}
else
{
Display_Error_Message();
}
Anytime you need to add a new string, you will have to add another "else if" statement to the ladder. Not only do you have to change the code, but you also have to retest it.
Lookup Table
You will need to understand function pointers for this technique and the map technique. Consider this a prerequisite.
Use a structure for mapping text strings to function pointers:
struct Text_Function_Pointer
{
const char * name;
Function_Pointer p_function;
};
static const Text_Function_Pointer table[] =
{
{"Larry", Process_Larry},
{"Felicity", Process_Felicity},
};
static const unsigned int table_size =
sizeof(table) / sizeof(table[0]);
//...
for (unsigned int i = 0; i < table_size; ++i)
{
if (search_name == table[i].name)
{
// Execute the processing function.
table[i].p_function(search_name);
break;
}
}
An issue with this technique is that all the function pointers must have the same signature. This is true for the map as well.
A nice feature is that the data in the table is constant, so it can be placed in Read-Only Memory.
Also, to add more associations, add an entry to the the table. The search / processing function hasn't changed, so it doesn't need to be tested again.
Map / Associative Array
Prerequisite: Function pointers.
Declare a std::map<std::string, Function_Pointer_Type>. Add your names and functions to the map:
std::map<std::string, Function_Pointer_Type> dispatch_table;
dispatch_table["Roger"] = Process_Roger;
dispatch_table["Felicity"] = Process_Felicity;
dispatch_table["Larry"] = Process_Larry;
//...
// Execute appropriate processing function:
(dispatch_table[search_name])();
One issue with this method is that the std::map data structure needs to be initialized; it can't be directly accessed or loaded from executable code.
Again, all functions must have the same signature.
Hash Table
The idea here is to have an array of function pointers or an array of structures with text & function pointers. Create a hash function that generates a unique array index based on the name string. Use the index to get the function pointer from the array, then execute the function via the function pointer.
Several solutions are available to you. You basically want to parse user input to fill your Square class attribute.
One way is to use the std::stoi family of functions:
std::vector<string> values { "Roger", "2", "3.5" };
std::string name = values[0]; // No problem, two strings
int width = std::stoi(values[1]); // stoi = stringToInt
float happiness = std::stof(values[2]); // stof = stringToFloat
I'm not sure why you'd need the for loop, unless there is something I didn't understand in your question. I'll update my answer accordingly.
Update 1
After reading other answers, I would like to propose my solution to your problem. As stated several times in my comments, this is not an easy answer !
I needed such a class to write a generic test engine, and this is the code I used. It works really well with any type of function (except for routines with a return type of void -- a simple template specialization would solve it though)
# include <functional>
# include <tuple>
template<int ...>
struct seq
{
};
template<int N, int ...S>
struct gens : gens<N - 1, N - 1, S...>
{
};
template<int ...S>
struct gens<0, S...>
{
typedef seq<S...> type;
};
struct callable_base
{
virtual void operator()() = 0;
virtual ~callable_base()
{ }
};
class Task
{
private:
template<class RT, class Functor, class ...Args>
struct functor : public callable_base
{
functor(RT& result, Functor func, Args ...args)
: _ret(result)
{
_func = func;
_args = std::make_tuple(args...);
}
void operator()()
{
_ret = call(typename gens<sizeof...(Args)>::type());
}
template<int ...S>
RT call(seq<S...>)
{
return (_func(std::get<S>(_args)...));
}
private:
std::function<RT(Args...)> _func;
std::tuple<Args...> _args;
RT& _ret;
};
public:
Task()
{
_functor = nullptr;
}
template<class RT, class Functor, class ...Args>
Task(RT& result, Functor func, Args... args)
{
_functor = new functor<RT, Functor, Args...>(result, func, args...);
}
void operator()()
{
(*_functor)();
}
~Task()
{
delete _functor;
}
private:
callable_base *_functor;
};
The idea behind this code is to hide the function signature in the inner class Task::functor and get the return value in the first parameter passed to the Task(...) constructor. I'm giving this code first because I think it might help some people, but also because I think it is an elegant solution to your problem. Bear in mind that to understand most of the code, you need solid C++ knowledge. I'll detail the code in subsequent updates if needed.
Here's how you'd use it:
int main()
{
int retVal;
std::string newName;
std::map<std::string, Task *> tasks {
{"setName", new Task(retVal, &Square::setName, &newName)}
...
}
/* Modify the name however you want */
...
tasks["setname"]();
}
This whole class could be optimized, of course, primarily thanks to C++14 and move semantics, universal references and all, but I kept it simple ~
A major problem is that you have to use pointers if you don't know the values of the parameters at the time you fill the task map. I'm working on another version to simplify this aspect, but I wanted to show you that C++ is not designed to do what you ask simply. Maybe you come from a functional or JS world, in which this would be trivial x)
Update 2
I just wanted to point out that with C++14, you could omit the first 3 structures that are here to help me expand my tuple in an argument list using interger_sequence
I have 1 question because I am pretty curious how to handle with such problem.
I have base class called "Pracownik" (Worker) and 2 subclasses which are made from public Pracownik;
- Informatyk (Informatic)
- Księgowy (Accountant)
Writing classes is easy. Made them pretty fast but I have small problem with main because I am helping friend with program but I was not using C++ for a while. So:
This is my header file "funkcje.h"
#include <iostream>
using namespace std;
class Pracownik
{
private:
string nazwisko;
int pensja;
public:
Pracownik(string="",int=0);
~Pracownik();
string getNazwisko();
int getPensja();
friend double srednia_pensja(int,Pracownik);
};
class Informatyk : public Pracownik
{
private:
string certyfikat_Cisco;
string certyfikat_Microsoft;
public:
Informatyk(string="",int=0, string="", string="");
~Informatyk();
void info();
};
class Ksiegowy : public Pracownik
{
private:
bool audytor;
public:
Ksiegowy(string="",int=0, bool=false);
~Ksiegowy();
void info();
};
double srednia_pensja(int,Pracownik);
These are definitions of my functions "funkcje.cpp"
#include "funkcje.h"
Pracownik::Pracownik(string a,int b)
{
nazwisko=a;
pensja=b;
}
Pracownik::~Pracownik()
{
}
string Pracownik::getNazwisko()
{
return nazwisko;
}
int Pracownik::getPensja()
{
return pensja;
}
Informatyk::Informatyk(string a, int b, string c, string d) : Pracownik(a,b)
{
certyfikat_Cisco=c;
certyfikat_Microsoft=d;
}
Informatyk::~Informatyk()
{
}
Ksiegowy::Ksiegowy(string a, int b, bool c) : Pracownik(a,b)
{
audytor=c;
}
Ksiegowy::~Ksiegowy()
{
}
void Informatyk::info()
{
cout<<"Nazwisko pracownika: "<<Pracownik::getNazwisko()<<endl;
cout<<"Pensja pracownika: "<<Pracownik::getPensja()<<endl;
cout<<"Certyfikat Cisco: "<<certyfikat_Cisco<<endl;
cout<<"Certyfikat Microsoft: "<<certyfikat_Microsoft<<endl;
}
void Ksiegowy::info()
{
cout<<"Nazwisko pracownika: "<<Pracownik::getNazwisko()<<endl;
cout<<"Pensja pracownika: "<<Pracownik::getPensja()<<endl;
cout<<"Audytor: ";
if(audytor)
cout<<"Tak"<<endl;
else
cout<<"Nie"<<endl;
}
double srednia_pensja(int a,Pracownik *b)
{
return 0;
}
And finally main!
#include <iostream>
#include "funkcje.h"
using namespace std;
int main()
{
Pracownik lista[10];
Pracownik *lista_wsk = new Pracownik[10];
Informatyk a("Kowalski1",1000,"Cisco1","Microsoft1");
Informatyk b("Kowalski2",2000,"Cisco2","Microsoft2");
Informatyk c("Kowalski3",3000,"Cisco3","Microsoft3");
Ksiegowy d("Kowalski4",4000,1);
Ksiegowy e("Kowalski5",5000,0);
lista[0]=a;
lista[1]=b;
lista[2]=c;
lista[3]=d;
lista[4]=e;
Informatyk *ab = new Informatyk("Kowalski1",1000,"Cisco1","Microsoft1");
Informatyk *ac = new Informatyk("Kowalski2",2000,"Cisco2","Microsoft2");
Informatyk *ad = new Informatyk("Kowalski3",3000,"Cisco3","Microsoft3");
Ksiegowy *ae = new Ksiegowy("Kowalski4",3000,1);
Ksiegowy *af = new Ksiegowy("Kowalski5",3000,0);
lista_wsk[0]=*ab;
lista_wsk[1]=*ac;
lista_wsk[2]=*ad;
lista_wsk[3]=*ae;
lista_wsk[4]=*af;
for(int i;i<5;i++)
{
lista[i].info();
cout<<endl;
}
cout<<endl;
// for(int i;i<5;i++)
// {
// lista_wsk[i].info();
// }
return 0;
}
Ok and here goes my questions:
I had to create array which is filled with base class objects "Pracownik".
Secondary i had to create array which is full of pointers to class "Pracownik" objects.
(Hope those 2 first steps are done correctly)
Next thing I had to write to array 3 objects of class Informatic and 2 of class Accountant.
So I ve created 5 objects manually and added them into the array in such way array[0]=a;. I guess this is still good.
Next thing i had to create and add similar objects to array of pointers using new. So I ve created array with new and pointers to objects with new. (Hope thats correct 2).
And FINALLY:
I had to use info() on added to array objects.
This is my main question if my array is type "Pracownik" and I want to use function info() from subclasses how should I do that? And how compiler will know if he should use info() from Accountant or Informatic while I am trying to show those information using "for".
In an array of Pracownik, the elements are of type Pracownik. Any information about the objects being of a subclass of Pracownik are lost when you copy the elements into the array.
This is called object slicing and leads to the fact that there is no way to invoke Informatyk::info() on these objects.
If you want to call methods of a subclass, you have to prevent object slicing by storing pointers or references in the array.
As Oswald says in his answer,
Pracownik * lista_wsk = new Pracownik[10];
allocates an array of 10 Pracownik objects. This is probably not what you want. With polymorphism involved, we usually want to deal with pointers or references. Hence, you'd want an array of Pracownik * pointers. Since you already know at compile-time that it will have 10 members, there is no need for a dynamic allocation here. I think you've meant to write
Pracownik * lista_wsk[10];
instead. Now we don't put objects but pointers to objects into the array. For example:
lista_wsk[2] = new Informatyk("Kowalski3", 3000, "Cisco3", "Microsoft3");
And then we can iterate over the items like so:
for (unsigned i = 0; i < 10; ++i)
std::cout << lista_wsk[i]->getNazwisko() << std::endl;
As you have already discovered, it is impossible to call a subclass function member on a superclass object. It would be possible to figure out the actual type at run-time yourslf by means of a cast.
for (unsigned i = 0; i < 10; ++i)
if (Informatyk * info_ptr = dynamic_cast<Informatyk *>(lista_wsk[i]))
info_ptr->info();
dynamic_cast returns a pointer to the target class if this is possible or a nullptr (which evaluates to false, hence the conditional) otherwise. Note however that this is considered very poor style. It is better to use virtual functions. Therefore, add
virtual void
info()
{
// Do what is appropriate to do for a plain Pracownik.
// Maybe leave this function empty.
}
to the superclass and again to the subclass
virtual void
info() // override
{
// Do what is appropriate to do for an Informatyk.
}
The function in the subclass with the same signature is said to override the function inherited from the superclass. Since the function is marked as virtual, the compiler will generate additional code to figure out at run-time what version of the function to call.
If you are coding C++11, you can make the override explicit by placing the keyword override after its type as shown above (uncomment the override). I recommend you use this to avoid bugs that arise from accidental misspelling or other typos.
Sorry if this question causes any confusion, I am looking to implement this and do not know the right way to approach such a thing.
For one of my projects I want to implement method chaining. I want to incorporate the following functions:
.toVector()
.toArray()
.toBool()
...
I have thought about placing these inside a namespace, e.g:
namespace Misc {
template<typename T, typename Inverse>
vector<T> toVector(Inverse begin, Inverser end) {
// ...
// ..
}
// ...
// ...
}
This is because there could be multiple classes, these classes MIGHT be able to use these functions, so therefore, it has to be OO rather than implementing each function again and again in different classes.
Let's say I have the following class Wav which reads in the data contained in a wav file:
class Wav {
public:
Wav();
Wav(string theFileName);
void getWaveData();
protected:
vector<double> data;
};
data is explicitly stored as a vector inside of the class.
In my main I want to be able to do the following:
int main()
{
Wav wave("file.wav");
int* data = wave.getWaveData().toArray(); // Method chaining to store as an array
}
I do not know whether or not this would be possible and if so how I would approach this without implementing all of the Misc functions over and over again inside each of the classes. Is there a way to communicate between the namespace and the class without having to include all of the functions over and over again?
I hope someone has a suggestion and any questions I will try to answer.
EDIT:
I have the written the following function:
template<typename T, typename Inverse>
T* toArray(Inverse begin, Inverse end)
{
size_t size = distance(begin, end);
auto pos = 0;
T* tmp = new T[size];
for(auto i = begin; i != end; i++)
{
tmp[pos] = *i;
pos++;
}
return tmp;
}
And if I have another function:
void process()
{
}
What would I therefore need to put inside the params of process in order to accept the following:
int* data = process(toArray<int>(
std::begin(vals),
std::end(vals)
);
This is the thing that is confusing me the most?
Regarding your new function:
In order to be able to call the process method below
int* data = process(toArray<int>( vals.begin(), vals.end()) );
the parameter for the process method should match the return type of the toArray method. Perhaps you can templatize the process method too as below.
template<typename T>
T* process(T* t)
{
//more code here
return t;
}
After adding the process method as above, the call to process will compile, but you will have to make the implementation of the process method generic enough to deal with different return types from other methods like toArray.
I have a struct Creature and a struct Game. Game is a "friend" of Creature.
In game I have
vector creatures;
and I add a creature x to that vector thourgh a function called addC
void addc (Creature& c){
creatures.push_back(c);
}
Now I'm in another function "foo" that is a public method of the struct Game.
void foo (Creature& c){
...
}
In that function I need to find another creature from the vector creatures that
matches some information from Creature c.
So I made another public method in Game called fooHelper
void fooHelper (char s, int x, int y){
bool found = false;
for (int i = 0; i < creatures.size() && (!found); ++i){
Creature& c = creatures[i];
if (x == c.x && y == c.y){
c.s = s;
found = true;
}
}
}
however when I check if the second creature's "s" member is being updated, it turns out that
it is not! I don't understand what I'm doing wrong since I'm pushing by references to the vector.
and I'm getting the creature by reference from the vector.
the vector in game looks like this
struct Game{
private:
vector<Creature> creatures;
...
}
struct Creature{
private:
char s;
int x; int y;
...
}
any help would be much appreciated!
This statement:
creatures.push_back(c);
Stores a copy of c into your vector: standard containers have value semantics. If you need reference semantics, you should store pointers into your vector.
Usually it is a good idea to use smart pointers, and which one to use depends on the ownership policy of your application. In this case, based on the information I could get from your question's text, it seems reasonable to let Game be the unique owner of all Creatures in the game (and therefore the only object which is responsible for the lifetime of the owned Creatures, and in particular for destroying them when they won't be needed anymore), so std::unique_ptr should be a good choice:
#include <memory> // For std::unique_ptr
struct Game{
private:
std::vector<std::unique_ptr<Creature>> creatures;
...
};
Your member function addc() would then become:
void addc(std::unique_ptr<Creature> c)
{
creatures.push_back(std::move(c));
}
And a client would invoke it this way:
Game g;
// ...
std::unique_ptr<Creature> c(new Creature());
g.addc(std::move(c));
Your foohelper() function, on the other hand, would be rewritten into something like this:
void fooHelper (char s, int x, int y) {
bool found = false;
for (int i = 0; i < creatures.size() && (!found); ++i){
std::unique_ptr<Creature>& c = creatures[i];
if (x == c->x && y == c->y) {
c->s = s;
found = true;
}
}
}
Finally, your class Game could return non-owning raw pointers (or references) to clients requiring access to the stored creatures.
When you push your creature reference into the vector, it's making a copy. It's a vector of type "Creature", and so it's making a copy from the reference that you give it. One solution would be to keep a vector of creature pointers.
edit - this question helps explain things a little better than I was able to on why you can't have a vector of references: Why can't I make a vector of references?