I am designing a code in c++ to deal with something like consumer and provider relations. The structure of the code is described as
class Datasource is used to store a ata (int number) in a queue which is shared by consumer and provider.
class Consumer is used to store consumers' information and more importantly, it can call the data from the common Datasource stored in a class called Status
class Provider is used to store providers' information and it can call the data from the common Datasource stored in a class called Status
in a class Status, I have an instance of Datasource created, the instance of Consumer and Provider will save the address of the instance of Datasource so to access the same Datasource in future.
// for Datasource
#ifndef __DATASRC_H_
#define __DATASRC_H_
#include <deque>
#include <random>
#include <chrono>
#include <algorithm>
using namespace std;
class Datasource
{
private:
std::deque<int> _src;
public:
Datasource() {reset();}
void assign(const Datasource &d)
{
_src.resize(d._src.size());
std::copy(d._src.begin(), d._src.end(), _src.begin());
}
void reset(void)
{
_src.clear();
for (int n=1; n<=1024; n++) _src.push_back(n);
std::srand(std::time(0));
random_shuffle(_src.begin(), _src.end());
}
int nextData(void)
{
if (!_src.empty())
{
int data = _src.front();
_src.pop_front();
return data;
}
else
{
cerr << "all data gone!" << endl;
return -1;
}
}
int size(void) {return _src.size();}
void show4(void)
{
cout << "next 3 numbers in the datasource: " << _src[0] << " " << _src[1] << " " << _src[2] << endl;
}
};
#endif // __DATASRC_H_
// for class Consumer
#ifndef __CONSUMER_H_
#define __CONSUMER_H_
#include "datasource.h"
#include <array>
#include <algorithm>
class Consumer
{
private:
std::vector<int> _mysrcs;
Datasource *src;
public:
Consumer() {reset();}
Consumer(Datasource *s):src(s) {reset();}
void setSrc(Datasource *s) {src = s;}
void assign(const Consumer &c)
{
_mysrcs.resize(c._mysrcs.size());
std::copy(c._mysrcs.begin(), c._mysrcs.end(), _mysrcs.begin());
src = c.src;
}
void reset(void)
{
_mysrcs.clear();
}
void addData(void)
{
// get data from Datasource
}
};
#endif // __CONSUMER_H_
// for class Provider
#ifndef __PROVIDER_H_
#define __PROVIDER_H_
#include <vector>
#include "Consumer.h"
using namespace std;
class Provider
{
private:
vector<Consumer> clients;
Datasource *src=nullptr;
public:
Provider() {reset();}
Provider(Datasource *s):src(s) {reset();}
void assign(const Provider &p)
{
clients.resize(p.clients.size());
std::copy(p.clients.begin(), p.clients.end(), clients.begin());
}
void setSrc(Datasource *s)
{
//cout << "In provider setSrc: src addr=" << &*src << " from addr=" << &*s <<endl;
src = s;
}
void reset(void)
{
clients.clear();
clients.push_back(Consumer(src));
if (src!=nullptr)
cout << "In provider reset: src size=" << src->size() << " src addr=" << &*src << endl;
}
};
#endif // __PROVIDER_H_
// for class Status
#ifndef __SRC_H_
#define __SRC_H_
#include "consumer.h"
#include "provider.h"
#include "datasource.h"
class Status
{
private:
Datasource src;
Consumer C;
Provider P;
public:
Status() {reset();}
Status(const Status &g)
{
src.assign(g.src);
C.assign(g.C);
P.assign(g.P);
}
void reset(void)
{
src.reset();
C.reset();
C.setSrc(&src);
P.reset();
P.setSrc(&src);
}
void test(void)
{
src.nextData(); // I get 3 numbers from datasource
src.nextData();
src.nextData();
src.show3(); // and the print the first 3 data in the queue after above actions
}
};
#endif // __SRC_H_
// main.cpp
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <fstream>
#include <random>
#include <algorithm>
#include <map>
#include <string>
#include <utility>
#include <iomanip>
#include "status.h"
int main(void)
{
Status s;
for (int i=0; i<1000; i++)
{
s.reset();
s.test();
}
return 0;
}
I have few questions about this code.
1) In the Status class, I have the datasource in Provider and Consumer refer to the one created in Status so Provider and Consumer is actually storing the address. Because I only want to maintain one copy of datasource in Status. The reason why I don't make Datasource outside Status so to maintain a global one for all class is that each Status should have it's own provider, consumers and datasource. So in my future code, I have to create many Status, each one should have it's own datasource. I wonder if this is a good way for some instance to store the address (pointer), any better way (or safe way) to do that in c++?
2) In the code main.cpp, I have 1 Status instance only, in each loop, I reset the Status (i.e. recreate 1024 elements of the datasource and shuffle it), in Status.test(), I pop up 3 datas (deque.pop_front) so to remove some numbers and show the first 3 elements in the rest of the queue. But running the code, you will see even I reset and shuffle the queue every time, I got the same output
loop 994
before reset: 1021
In provider reset: src size=1024 src addr=0x28fec8
next 3 numbers in the datasource: 265 555 587
loop 995
before reset: 1021
In provider reset: src size=1024 src addr=0x28fec8
next 3 numbers in the datasource: 265 555 587
loop 996
before reset: 1021
In provider reset: src size=1024 src addr=0x28fec8
next 3 numbers in the datasource: 265 555 587
loop 997
before reset: 1021
In provider reset: src size=1024 src addr=0x28fec8
next 3 numbers in the datasource: 265 555 587
loop 998
before reset: 1021
In provider reset: src size=1024 src addr=0x28fec8
next 3 numbers in the datasource: 265 555 587
loop 999
before reset: 1021
In provider reset: src size=1024 src addr=0x28fec8
next 3 numbers in the datasource: 265 555 587
if you read the code in datasource.h, I do the reshuffle with the std library and before the suffle, I reseed it with std::srand(std::time(nullptr)). I have no idea what cause the problem :)
Aucun commentaire:
Enregistrer un commentaire