c++ access array data of shared library - c++

I am coding in stm32. Basically, I want to access a bool array data from another library. This is a header file of AP_Tmxk_LIDARScanner library stored data in scan.isObstacle which is a bool array. Also I made a return function named getObstacle(). Another library named AP_Tmxk_VFH to access data from getObstacle(). Is that ok? Or which is the way to copy that array in AP_Tmxk_VFH. Thanks for your help.
AP_Tmxk_LIDARScanner
class AP_Tmxk_LIDARScanner {
private:
struct{
bool isObstacle[180] = {}; //1: unsafe; 0:safe
bool available = false;
}scan;
public:
AP_Tmxk_LIDARScanner();
void init();
void update();
bool getAvailable() const{
return scan.available;
}
bool getObstacle() const{
return scan.isObstacle;
}
};
AP_Tmxk_VFH.h
class AP_Tmxk_VFH {
private:
struct{
bool Certain_Value[180] = {};
}sector;
const AP_Tmxk_LIDARScanner &_lidarscanner;
public:
// Constructor
AP_Tmxk_VFH(const AP_Tmxk_LIDARScanner &_lidarscanner);
void init();
void update();
};
AP_Tmxk_VFH.cpp
AP_Tmxk_VFH::AP_Tmxk_VFH(const AP_Tmxk_LIDARScanner &lidarscanner) :
_lidarscanner(lidarscanner)
{}
void AP_Tmxk_VFH::update()
{
if(_lidarscanner.getAvailable()){
sector.Certain_Value = _lidarscanner.getObstacle()
}
}

Here I modfiy my code format.
AP_Tmxk_LIDARScanner.h
class AP_Tmxk_LIDARScanner {
private:
struct{
bool isObstacle[180]= {}; //1: unsafe; 0:safe
bool available = false;
}scan;
public:
AP_Tmxk_LIDARScanner();
void init();
void update();
bool getAvailable() const{
return scan.available;
}
void getObstacle(int (&array)[180]);
};
AP_Tmxk_LIDARScanner.cpp
void AP_Tmxk_LIDARScanner::getObstacle(int (&array)[180])
{
for(int i=0; i<180; i++){
if(scan.isObstacle[i]){
array[i] = (array[i]+1 >= 5) ? 5 : array[i]+1;
}
else{
array[i] = (array[i]-1 >= 0) ? array[i]-1 : 0;
}
}
}
AP_Tmxk_VFH.h
class AP_Tmxk_VFH {
private:
struct{
int Certain_Value[180] = {};
}sector;
class AP_Tmxk_LIDARScanner &_lidarscanner;
public:
// Constructor
AP_Tmxk_VFH(class AP_Tmxk_LIDARScanner &_lidarscanner);
void init();
void update();
};
AP_Tmxk_VFH.cpp
AP_Tmxk_VFH::AP_Tmxk_VFH(class AP_Tmxk_LIDARScanner &lidarscanner) :
_lidarscanner(lidarscanner)
{}
void AP_Tmxk_VFH::update()
{
if(_lidarscanner.getAvailable()){
_lidarscanner.getObstacle(sector.Certain_Value);
}
}

Related

Convert c++98 code to new c++17 code when using std::vector of pointers

i dont what to manage or less as i can manage raw pointers note in the example i have to delete the object before removeing it from the vector i want to avoid it it here and later
what will be good case to convert this code to using unique_ptr or shared_ptr
class GameState
{
public:
virtual bool onEnter() = 0;
virtual bool onExit() = 0;
virtual std::string getStateID() const = 0;
};
class MenuState : GameState
{
public:
MenuState(){};
virtual ~MenuState(){};
bool onEnter(){};
bool onExit(){};
std::string getStateID() const;
private:
static const std::string s_menuId;
};
class StateMechine
{
public:
void pushState(GameState* pState)
{
m_gameStates.pop_back(pState);
m_gameStates.back()->onEnter();
}
void changeState(GameState* pState)
{
if(!m_gameStates.empty())
{
if(m_gameStates.back()->onExit())
{
delete m_gameStates.back();
m_gameStates.pop_back();
}
}
}
private:
std::vector<GameState*> m_gameStates;
}
int main(int argc ,char** argv)
{
GameState *gs = new MenuState();
StateMechine sm;
sm.pushState(gs);
sm.changeState(gs);
}
The std::vector<GameState*> can be replaced with a std::vector<std::unique_ptr<GameState>>. That way a call to m_gameStates.pop_back() will delete the corresponding object.
class StateMechine
{
public:
void pushState(std::unique_ptr<GameState> pState)
{
m_gameStates.push_back(std::move(pState));
m_gameStates.back()->onEnter();
}
void changeState()
{
if(!m_gameStates.empty())
{
if(m_gameStates.back()->onExit())
{
m_gameStates.pop_back();
}
}
}
private:
std::vector<std::unique_ptr<GameState>> m_gameStates;
};
int main(int argc ,char** argv)
{
StateMechine sm;
sm.pushState(std::make_unique<MenuState>());
sm.changeState();
}

Undefined reference to vtable for class

I have the class DvQkdLdpcTxMessageProcessorReceiver as follow:
#ifndef DV_QKD_LDPC_TX_MESSAGE_PROCESSOR_RECEIVER_H_
#define DV_QKD_LDPC_TX_MESSAGE_PROCESSOR_RECEIVER_H_
#include "netxpto_20200819.h"
#include "dv_qkd_message_processor_common_20200819.h"
class DvQkdLdpcTxMessageProcessorReceiver : public Block
{
public:
DvQkdLdpcTxMessageProcessorReceiver(std::initializer_list<Signal*> InputSig, std::initializer_list<Signal*> OutputSig) : Block(InputSig, OutputSig) {};
void initialize(void);
bool runBlock(void);
private:
// Input Parameters ##################################################################################
// State Variables ###################################################################################
std::vector<t_message> storedMessages{};
// Basis Reconciliation
t_integer messageReconciliationMaximumDataLength{ 4096 };
CircularBuffer<t_binary> BasesFrom{ messageReconciliationMaximumDataLength };
// Parameter Estimation
t_integer messageParameterEstimationMaximumDataLength{ 100 };
t_integer numberOfProcessedBits{ -1 };
CircularBuffer<t_integer> SeedFrom{ 10 };
CircularBuffer<t_integer> RatioFrom{ 10 };
CircularBuffer<t_integer> NumberOfBitsPerEstimationBlockFrom{ 10 };
CircularBuffer<t_binary> DataFrom{ 10*(size_t) messageParameterEstimationMaximumDataLength };
// Error correction - Parities
std::vector<t_integer> parityIn{};
bool errCorrParitiesStarted{ false };
// Sindrome
t_integer messageSindromeMaximumDataLength{ 5000 };
CircularBuffer<t_binary> Sindrome{ messageSindromeMaximumDataLength };
// Error correction - Permutations
std::vector<t_integer> permutationsIn{};
bool errCorrPermStarted{ false };
// Error correction - BER
std::vector<t_integer> errCorrBerIn{};
bool errCorrBerStarted{ false };
// Privacy amplification seeds
std::vector<t_integer> privacySeedsIn{};
bool privacySeedsStarted{ false };
bool outputReceivedData(std::vector <t_integer>& dataVector, Signal& outputSignal, bool &started);
};
#endif // !MESSAGE_PROCESSOR_RECEIVER_H_
The parent class is defined as:
class Block {
public:
/* Methods */
Block(){};
Block(std::vector<Signal*> &InputSig, std::vector<Signal*> &OutputSig);
Block(std::initializer_list<Signal*> InputSig, std::initializer_list<Signal*> OutputSig); // since C++11
//void initializeBlock(std::vector<Signal*> InputSig, vector<Signal*> OutputSig);
void initializeBlock();
virtual void initialize(void) {};
//bool runBlock();
virtual bool runBlock();
void terminateBlock();
virtual void terminate(void) {};
void closeOutputSignals();
void setNumberOfInputSignals(int nOfInputSignal) { numberOfInputSignals = nOfInputSignal; };
int getNumberOfInputSignals() { return numberOfInputSignals; };
void setNumberOfOutputSignals(int nOfOutputSignal) { numberOfOutputSignals = nOfOutputSignal; };
int getNumberOfOutputSignals() { return numberOfOutputSignals; };
void setLogValue(bool lValue) { logValue = lValue; }
bool getLogValue() { return logValue; }
void setFirstRun(bool fRun) { firstRun = fRun; }
bool getFirstRun() { return firstRun; }
void setFirstTime(bool fTime) { firstTime = fTime; }
bool getFirstTime() { return firstTime; }
void setTerminated(bool t) { terminated = t; }
bool getTerminated() { return terminated; }
std::string getSignalsFolderName();
void setVerboseMode(t_bool vMode) { verboseMode = vMode; }
t_bool getVerboseMode(void) { return verboseMode; }
void setVerboseFolderName(t_string vFolderName) { verboseFolderName = vFolderName; }
t_string getVerboseFolderName(void) const { return verboseFolderName; }
std::vector<Signal *> inputSignals;
std::vector<Signal *> outputSignals;
private:
bool logValue{ true };
bool firstRun{ true }; // To be deleted, 2020/02/04, the name firstTime is more comum
bool firstTime{ true };
bool terminated{ false };
t_bool verboseMode{ true };
int numberOfInputSignals{ 1 };
int numberOfOutputSignals{ 1 };
t_string verboseFolderName{ "verbose" };
};
when I make in the terminal, I receive the following error:
undefined reference to `vtable for DvQkdLdpcTxMessageProcessorReceiver'
How could I fix it? I searched a lot about the error (I tried to find pure virtual method or inline functions and ...), but no result. Thank you.

upcasting variable in derived class c++

How to change the type of a inherited variable in the derived class?
I have the following classes:
class Position;
class StonePosition;
class Position {
public:
Position() {}
};
class StonePosition : public Position {
int count;
public:
StonePosition(const int count) { this->count = count; }
int getCount() { return this->count; }
void setCount(int count) { this->count = count; }
friend ostream& operator<<(ostream&, StonePosition);
};
class Board {
protected:
Position* crrPos;
public:
Board() { }
Position* getCrrPos() { return crrPos; }
void setCrrPos(Position* pos) { crrPos=pos; }
};
class StoneBoard : public Board {
public:
StoneBoard(const int &count) { this->crrPos=new StonePosition(count); } //<----------------
StonePosition* getCrrPos() { return (StonePosition*)crrPos; }
void setCrrPos(StonePosition* pos) { crrPos=pos; }
};
Place in which the problem is marked by an arrow. I need to change the type of a variable from Position to StonePosition in the StoneBoard class. I found an option that can be used upcasting, but it works only within a single method, and I need to change the variable for the entire class.
The problem was solved, look at my answer.
The variable "crrPos" is not of type Position it is of type pointer to Position and this is significant because a pointer to Position can point to a Position or a class derived from Position without losing anything.
If you design your classes well, and make use of virtual functions, you can usually avoid the need to upcast entirely.
#include <iostream>
class Base {
public:
virtual void foo() { std::cout << "Base::foo()\n"; }
virtual bool isDerived() const { return false; }
};
class Derived : public Base {
public:
void foo() override { std::cout << "Derived::foo()\n"; }
bool isDerived() const { return true; }
};
int main() {
Base* crrPos = new Derived;
crrPos->foo();
bool isDerived = crrPos->isDerived();
std::cout << isDerived << '\n';
delete crrPos;
}
Live demo: http://ideone.com/UKcBaA
The problem has been solved, I just use the projection ((StonePosition*)Position*):
#include <iostream>
using namespace std;
class Position;
class StonePosition;
class Position {
public:
Position() {}
};
class StonePosition : public Position {
int count;
public:
StonePosition(const int count) { this->count = count; }
int getCount() { return this->count; }
void setCount(int count) { this->count = count; }
friend ostream& operator<<(ostream&, StonePosition);
};
template <typename TPos> class TBoard {
protected:
TPos* crrPos;
public:
TBoard() { }
TPos* getCrrPos() { return crrPos; }
void setCrrPos(TPos* pos) { crrPos=pos; }
};
class Board {
protected:
Position* crrPos;
public:
Board() { }
Position* getCrrPos() { return crrPos; }
void setCrrPos(Position* pos) { crrPos=pos; }
};
class StoneBoard : public Board {
public:
StoneBoard(const int &count) { this->crrPos=new StonePosition(count); }
Position* getCrrPos() { return crrPos; }
void setCrrPos(Position* pos) { crrPos=pos; }
};
int main(){
StoneBoard s(7);
cout<<((StonePosition*)s.getCrrPos())->getCount();//<----right here
system("pause");
return 0;
}
And its working nice :)

Class factory to create derived classes c++

I'm currently learning about class factory patterns with C++. I keep having errors while trying to implement the factory. Suppose I have an abstract class and two derived classes. What I want the factory to do is to create a new object of the base class like so: Ball *sc = new SoccerBall();
I am not sure on how to implement this, I have tried but of no avail. What do I need to fix?
class Ball
{
public:
Ball();
virtual ~Ball();
virtual int getSize() const = 0;
virtual void setBallSize(int s) = 0;
virtual string ballManufacturer() const = 0;
protected:
int ballSize;
}
class Soccerball:public Ball
{
public:
Soccerball();
Soccerball(int size);
~Soccerball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class Soccerball:public Ball
{
public:
Soccerball();
Soccerball(int size);
~Soccerball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class Basketball:public Ball
{
public:
Basketball();
Basketball(int size);
~Basketball();
int getSize() const;
void setBallSize(int s);
string ballManufacturer() const;
}
class BallFactory
{
public:
Ball* createBall(string s)
{
if(s == "Soccer")
{
return new Soccerball(5);
}
if(s == "Basket")
{
return new Basketball(6);
}
}
}
This how your code will work, but above when you are posting a question you should provide "Short Self Contained Correct Code" and make easy for people to understand your problem easily.
#include <iostream>
using namespace std;
class Ball
{
public:
Ball()
{
cout<<"Ball ctr"<<endl;
}
virtual ~Ball()
{
}
virtual int getSize() const = 0;
virtual void setBallSize(int s) = 0;
virtual string ballManufacturer() const = 0;
protected:
int ballSize;
};
class Soccerball:public Ball
{
public:
Soccerball()
{
cout<<"create Default Soccer Ball "<<endl;
}
Soccerball(int size)
{
cout<<"create Soccer Ball "<<size<<endl;
}
~Soccerball()
{
}
int getSize() const
{
return ballSize;
}
void setBallSize(int s)
{
ballSize = s;
}
string ballManufacturer() const
{
return "";
}
};
class Basketball:public Ball
{
public:
Basketball()
{
cout<<"create default Baseket Ball "<<endl;
}
Basketball(int size)
{
cout<<"create Baseket Ball "<<size<<endl;
}
~Basketball()
{
}
int getSize() const
{
return ballSize;
}
void setBallSize(int s)
{
ballSize = s;
}
string ballManufacturer() const
{
return "";
}
};
class BallFactory
{
public:
//Factory method
static Ball* createBall(string s)
{
if(s == "Soccer")
{
return new Soccerball(5);
}
if(s == "Basket")
{
return new Basketball(6);
}
}
};
int main()
{
Ball* ptr = BallFactory::createBall("Soccer");
return 0;
}
But you also need to understand how Factory design pattern works and how a namesake virtual constructor is created and why you would use a parameterized factory. Or could you use a template factory.

Calling thread on member function

Sorry for the long example, but the question is simple. I'm using basic Visitor Pattern, with a mediator to manage several concrete Visitor_pick : public DataVisitor objects. The conrete mediator, SimulatorMediator, fills a list with Visitor_pick objects, then wants to call std::thread on a DataVisitor member function. I have tried several variants, using mem_fun1_t<>, etc., with no luck. Can't compile. What is the correct syntax?
The call in question should be at line 205 - I'd like to attach threads to v->visit_SpreadData, a unary function, then populate threadVec. Any help would be appreciated.
#include <iostream>
#include <ostream>
#include <iterator>
#include <list>
#include <vector>
#include <algorithm>
#include <thread>
class PublishEvent;
class Subscriber
{
public:
virtual void update(const PublishEvent *e) = 0;
~Subscriber() = default;
};
class Publisher
{
public:
void attach(Subscriber*);
void detach(Subscriber*);
void notify(const PublishEvent*);
protected:
std::list<Subscriber*> subscribers_;
};
inline void Publisher::
notify(const PublishEvent *e)
{
for (auto &s : subscribers_)
s->update(e);
}
inline void Publisher::
attach(Subscriber *s)
{
subscribers_.push_back(s);
}
inline void Publisher::
detach(Subscriber *s)
{
// inefficient for large nubmer of susbscribers
subscribers_.remove(s);
}
class Mediator;
class SpreadData;
class DataElement;
class DataVisitor : public Publisher, public Subscriber
{
public:
virtual ~DataVisitor() {}
// visit method
virtual void visit_SpreadData(SpreadData *SD) = 0;
// from Publisher::
void update(const PublishEvent *e) override;
void setMediator(Mediator *m)
{
m_ = m;
}
float get_payload() const
{
return payload_;
}
void set_payload(float p)
{
payload_ = p;
}
virtual void gendata(DataElement*) = 0;
protected:
DataVisitor() {}
private:
Mediator *m_;
float payload_;
};
class DataElement
{
public:
virtual ~DataElement() {};
void Accept(DataVisitor&);
protected:
DataElement() {};
};
void DataElement::Accept(DataVisitor &d)
{
d.gendata(this);
}
class SpreadData : public DataElement
{
public:
typedef std::vector<float> return_data_type;
SpreadData() { initiate(); };
SpreadData(std::string filename) { initiate();};
void printdata() const
{
std::copy(data_.begin(),
data_.end(),
std::ostream_iterator<float>(std::cout, " : "));
std::cout << std::endl;
}
return_data_type getdata() const
{
return data_;
}
private:
void initiate()
{
for(int i=0;i<100;i++)
data_.push_back(static_cast<float>(i));
}
return_data_type data_;
};
void DataVisitor::update(const PublishEvent *e)
{
// implementation details
};
template<int N>
class Visitor_pick : public DataVisitor
{
public:
Visitor_pick()
{set_payload(0.); }
// from DataVisitor
void visit_SpreadData(SpreadData*) override;
// from DataVisitor
void gendata(DataElement*);
};
template<int N>
void Visitor_pick<N>::visit_SpreadData(SpreadData *SD)
{
SD->Accept(*this);
}
template<int N>
void Visitor_pick<N>::gendata(DataElement *d)
{
// implementation details
SpreadData *SD = dynamic_cast<SpreadData*>(d);
SpreadData::return_data_type r = SD->getdata();
set_payload(r[N]);
}
class Mediator
{
public:
virtual ~Mediator() = default;
virtual void mediate(DataElement*) = 0;
protected:
Mediator() = default;
virtual void CreateVisitors() = 0;
std::list<DataVisitor*> visitors_;
};
class Mediator_1 : public Mediator
{
public:
Mediator_1()
{
CreateVisitors();
}
void mediate(DataElement*);
private:
void CreateVisitors();
};
void Mediator_1::CreateVisitors()
{
visitors_.push_back(new Visitor_pick<37>());
visitors_.push_back(new Visitor_pick<42>());
visitors_.push_back(new Visitor_pick<47>());
visitors_.push_back(new Visitor_pick<52>());
visitors_.push_back(new Visitor_pick<57>());
}
void Mediator_1::mediate(DataElement *SD)
{
typedef std::mem_fun1_t<void,DataVisitor,SpreadData*> Visitor_fn;
std::cout << "Mediating hard..." << std::endl;
std::vector<std::thread> threadVec;
for(auto &v : visitors_)
{
// Use Visitor_fn to spawn thread on
// unary function v->visit_SpreadData,
// place at back of threadVec
}
for_each(threadVec.begin(), threadVec.end(),
std::mem_fn(&std::thread::join));
for(auto &v : visitors_)
std::cout << "Payload: " << v->get_payload() << std::endl;
}
int main(int argc, char **argv)
{
SpreadData *SD = new SpreadData();
Mediator_1 *M = new Mediator_1();
M->mediate(SD);
delete SD;
delete M;
return 0;
}