Unique Identifier for sent messages in good programming practice - c++

A system send xml warning messages. To put the xml file together, a class was created so the warning could be generated before translating it to xml. Each message has to have an unique ID.
How unique? The IDs go from 3400 until 3500. If maximum is reached, the ID is reset.
#ifndef WARNINGMESSAGE_H
#define WARNINGMESSAGE_H
#include <ctime>
static unsigned int control_ID = 3399;
//Effect Codes:
const unsigned int TRAFFIC_FREE = 2;
//(...)
class WarningMessage{
public:
//setters
void setActionID();
//getters
//(...)
private:
unsigned int actionID; //to be controlled by control_ID
};
#endif // WARNINGPARAMVEHICLE_H
And in the cpp file, when the id of a message needs to be setted, the following is executed:
#include "project/include/warningmessage.h"
//setters
void WarningParamVehicle::setActionID(){
if(control_ID == 3500){
control_ID = 3399;
}
control_ID++;
actionID = control_ID;
}
Another detail that is important, the space in memory for this class message is given just once. Every time another message has to be sent, the instance is deleted and re-created as such:
void WarningDetector::createWarning(){
delete currentWarningMessage; // delete previous warning instance
currentWarningMessage = new WarningMessage();
(...)
}
and lastly, currentWarningMessage was declared in warning detector as a pointer:
WarningMessage* currentWarningMessage;
I can notice the bad programming practice in declaring the variable control_ID in the header file and outside of the class scope, however, given scenario coding like this look optimized. Is there a better way to solve this unique identifier problem seen here? Thanks a lot in advance

Good programming practice could include single responsibilities. For instance, setting the action id for the current message could be decoupled from deciding on the action id for the next message. This could enable consistent behavior when exceptions happen during the construction of a WarningMessage (if you get a chance to fix the cause of the exception you might want to try again to create the WarningMessage and expect the same actionId).
To address that and the other comments above you could for instance:
make control_ID a private static member of WarningMessage (setActionID is currently a member of WarningMessage)
remove the public setter setActionID and initialize actionID in the initialization list instead
manage control_ID, last thing inside the constructor (in case there are exceptions)
In the header:
#ifndef WARNINGMESSAGE_H
#define WARNINGMESSAGE_H
#include <ctime>
//Effect Codes:
const unsigned int TRAFFIC_FREE = 2;
//(...)
class WarningMessage{
public:
WarningMessage();
//remove public setters if your use case doesn't require them
//getters
//(...)
private:
// deconstructing control_ID
static const unsigned ID_COUNT = 100;
static const unsigned ID_START = 3400;
static unsigned idOffset = 0;
const unsigned int actionID; //to be controlled by control_ID
};
#endif // WARNINGPARAMVEHICLE_H
And in the cpp file:
#include "project/include/warningmessage.h"
unsigned WarningMessage::idOffset = 0;
WarningMessage::WarningMessage()
: actionId(ID_START + idOffset) /* ... */
{
// increment idOffset only when you are sure that it is safe
++idOffset;
idOffset %= ID_COUNT;
}
Note that this is not going to work in a multi-threaded environment, but that doesn't seem to be your concern at the moment

I would create 2 constants IDMIN = 3499 and IDMAX = 3500 to avoid having magic numbers in an implementation file. Those constants should be static const members of class WarningMessage.
I would set control_ID as a static variable in the method WarningParamVehicle::setActionID (isn't it WarningMessage::setActionID ?). It would then give :
class WarningMessage{
public:
static const int IDMIN = 3499;
static const int IDMAX = 3500;
//setters
void setActionID();
...
and later in implementation :
void WarningParamVehicle::setActionID(){
static int control_ID = WarningMessage::IDMIN;
if(control_ID == IDMAX){
control_ID = IDMIN;
}
control_ID++;
actionID = control_ID;
}

Related

How to store list of register base addresses in a static class member and count them?

I'm working with microcontrollers for embedded devices. These controllers provide multiple peripherals which a configured and controlled using registers. A peripheral usually has a certain register set associated with it. Several peripherals of the same type (e.g., Timer0, Timer1, ...) have the same register set but they are located at different base addresses.
Usually the manufacturer provides header files that define the registers and related addresses for each peripheral.
For example, this header file for a timer peripheral could be provided:
typedef struct {
uint32_t IR;
uint32_t TCR;
uint32_t TC;
uint32_t MCR;
uint32_t MR[4];
} CTIMER_Type;
#define CTIMER0_BASE (0x40008000u)
#define CTIMER0 ((CTIMER_Type *)CTIMER0_BASE)
#define CTIMER1_BASE (0x40009000u)
#define CTIMER1 ((CTIMER_Type *)CTIMER1_BASE)
#define CTIMER_BASE_PTRS { CTIMER0, CTIMER1 }
These header files are specific for a certain device. In this example, information about a timer peripheral is provided: there are two timers and their register set are located at CTIMER0 a
nd CTIMER1, respectively.
Using C, I'd pull the list of base register addresses CTIMER_BASE_PTRS into my implementation using:
static CTIMER_Type * ctimers[] = CTIMER_BASE_PTRS;
static int timers_count = sizeof(ctimers)/sizeof(*ctimers);
Now using C++, I want to write a driver class and include the list of available timers CTIMER_BASE_PTRS in my code. Also I want to calculate the number of timers available.
I came up with this code which you can try for yourself:
#include <stdio.h>
#include <type_traits>
#include <stdint.h>
/* usually provided by chip manufacturer through chip specific include file */
typedef struct {
uint32_t IR;
uint32_t TCR;
uint32_t TC;
uint32_t MCR;
uint32_t MR[4];
} CTIMER_Type;
#define CTIMER0_BASE (0x40008000u)
#define CTIMER0 ((CTIMER_Type *)CTIMER0_BASE)
#define CTIMER1_BASE (0x40009000u)
#define CTIMER1 ((CTIMER_Type *)CTIMER1_BASE)
#define CTIMER_BASE_PTRS { CTIMER0, CTIMER1 }
/* end manufacturer include file */
static CTIMER_Type * ctimers[] = CTIMER_BASE_PTRS;
class TimerDriver_base {
public:
TimerDriver_base() {
printf("No of timers available:%i\n", timers_count);
}
private:
constexpr static int timers_count = sizeof(ctimers)/sizeof(*ctimers);
// A
// uncommenting next line prompts compiler error: 'reinterpret_cast' from integer to pointer
//constexpr static CTIMER_Type * ctimers1[] = CTIMER_BASE_PTRS;
// B
static CTIMER_Type * ctimers2[];
// uncommenting next line prompts compiler error: invalid application of 'sizeof' to incomplete type 'CTIMER_Type* []'
// constexpr static int timers_count2 = sizeof(ctimers2)/sizeof(*ctimers2);
};
// B
CTIMER_Type * TimerDriver_base::ctimers2[] = CTIMER_BASE_PTRS;
int main()
{
TimerDriver_base MyTimer;
}
I tried to include the list of timers ctimers[] into the driver class using two approaches:
A) using the define CTIMER_BASE_PTRS to initialize a static constexpr. That failed - seemingly as C++ does not allow the cast in the constexpr.
B) using the define CTIMER_BASE_PTRS to initialize a static array of pointers. That's ok, however, I can not calculate the size of it.
As both approaches failed, I resorted to a static global variable (as in the C code). But that's probably due to my limited proficiency in C++. Thus I'd like to know:
How do I do define a the list of drivers ctimers[] inside a class and calculate the length of the list?
Thanks.
Dan
as reinterpret_cast is not allowed in constant expression, both would fail*
you can use inline static instead.
I'd also use c++ container (but raw array would work as well).
struct TimerDriver_base {
inline static std::array ctimers2 = CTIMER_BASE_PTRS;
static constexpr auto size = std::tuple_size<decltype(ctimers2)>::value;
// size is also accessible as `TimerDriver_base::ctimers2.size()`
};
https://godbolt.org/z/4eq9j79fY
* if you change the namespace scope one to this it'd also fail
static constexpr CTIMER_Type * ctimers[] = CTIMER_BASE_PTRS;

Detecting and clearing wrong object imported from dll in C++

I have a dll ("so.dll") definition as follow, in which I have a function TestWrongClass, which returns a pointer
to a class object (TestWrongClass).
/////// "IOReader.h" //////////////
class IOReader
{
public :
IOReader() {};
virtual ~IOReader() {};
virtual bool open(const std::string &format,
const std::string &fileName, const int mask) = 0;
std::string errorMessage;
};
// "IOReader.h" Ends Here
// ---- so.dll ---- /
//////////////// sio.h ////////////
#ifdef SEIO_EXPORTS
#define SEIO_API __declspec(dllexport)
#else
#define SEIO_API __declspec(dllimport)
#endif
#include <string>
#include "IOReader.h"
class SReaderIO : public IOReader
{
public:
SReaderIO() {};
bool open(const std::string &format,
const std::string &fileName, const int mask)
{
return true;
}
};
class TestWrongClass
{
public:
TestWrongClass() { };
bool open(const std::string &format,
const std::string &fileName, const int mask)
{
return true;
}
};
SEIO_API TestWrongClass* CreateIOReader()
{
TestWrongClass * module = new TestWrongClass();
return module;
}
//// sio.h ends here ///////
//in the main executable I am loading the dll on run time
// and after creating a object of type TestWrongClass,
//I explicitly try to cast it with the wrong object, as follows
/// Main Source //
#include <iostream>
#include <windows.h>
#include "IOReader.h"
int main ()
{
HMODULE hDLL=LoadLibrary(L"sIO.dll");
CreateSealafineReaderFn _funcSelafinCreator = NULL;
_funcSelafinCreator = (CreateSealafineReaderFn) GetProcAddress (hDLL,
"CreateIOReader");
// Method 1
void *Iref = (_funcSelafinCreator)();
IOReader * locReader = NULL;
locReader = reinterpret_cast <IOReader *>(Iref); // but how to check
// that object locReader is not of base type IOReader
// so that I may call delete Iref
// If I try to do as follow, then I get illegal error from compiler
// locReader = dynamic_cast <IOReader *>(Iref); // illegal
// Method 2
try
{
locReader = dynamic_cast <IOReader *>((_funcSelafinCreator)());
// works but how can I check wrong casting and catch exception
} catch (std::bast_cast)
{
// how to clear the object created by CreateIOReader
}
}
//
The reason why I doing this process is to check if any dlls, which the main program will be scanning from the dll directory
may be having a method of the same name, however return pointer type of the created object by the method may be different, which is not desired.
(In the above mentioned case the method is CreateIOReader)
if I use dynamic_cast, I can check for the bad_cast exception, however the object will be already created in the dll, and won't be freed, since I
don't have access to the internal code of the dll.
the above method which I have given using reintepret_cast works, however I cannot check whether the correct object type is returned or not.
if get to know by some method that if the casting is not of correct type, then I can call delete on the Iref pointer "delete Iref" to clear the object from the heap.
Is there any method to check creation of wrong object by the method CreateIOReader, and thus delete it from the executable source code
For this problem dynamic_cast cannot help you. The issue is that you do not know the real return type of your function, and are just pretending it is IOReader*, when it could in fact be something else (i.e. TestWrongClass*). Under aliasing rules this is not allowed.
Contrast this with the situation:
class IBase { ... };
class IOReader : public IBase { ... };
class TestWrongClass : public IBase { ... };
where you also know that your function returns an IBase*. Here indeed a dynamic cast could help you, as IOReader and TestWrongClass have common ancestry, and it would be valid to refer to either through a IBase*.
I have to say it is a strange problem to have: a call to a library function where you have no idea what might be returned. I would suggest changing the design somewhat. You could (amongst other things):
Create the unified hierarchy as per above
Have the call return something like std::pair<int, void*>, where the int (or enum) would be a reliable way to determine what is being returned, after which you could reinterpret_cast the void*
If you choose approach 1, then to address your deletion problem, you could add a function like destroy() to the IBase interface, which would cause the library to delete the object (note: it is bad idea to delete yourself objects that are given to you by an external library).
If you choose approach 2, then perhaps you could have a library function like void destroy(int, void*), to which you could pass the members of your std::pair in case you received something other than what you wanted. The library could then use these to cast the void* back into the right thing to delete it internally.

How can I store values in my class private array? c++11

I have something that looks like this
class RestaurantCheck
{
private:
static const int MENU_LENGTH = 10;
static const string menu[MENU_LENGTH] = {"Gumbo", "Shrimp", etc...}
Right off the bat, I have a problem. I know I can't initialize the data in the array as it is now, so I tried this ...
class RestaurantCheck
{
private:
static const int MENU_LENGTH = 10;
static const string menu[MENU_LENGTH];
void displayMenu();
public:
void showMenu()
{
RestaurantCheck thisMenu;
thisMenu.displayMenu();
}
void RestaurantCheck::displaymenu()
{
menu[0] = "Shrimp"
menu[1] = "Gumbo"
etc...
cout << menu[0]
etc...
However I am unable to store data in the array like that as well.
How the heck am I supposed to store data in this array? As part of the assignment, the array must be a const static, it must be in private, and the displayMenu must also be private, called by a public function.
I hope what I'm getting at is clear, if not I'll try to provide more information.
EDIT:
I can not edit anything from the instructors source file. The source file is already created, and he will be using his own (provided) to test both my class file and my header file. Thus it needs to be initiated outside of sourcefile.
You are falling into the same trap as many before you. Your array is const, so it must be initialized when declared. But you can not initialize static string arrays in the class body. What do you do? You initialize it outside!
like this:
in your .h file:
static const std::string menu[10];
in your .cpp file:
const std::string RestaurantCheck::menu[10] = {"Shrimp", "Calamari", "Listeria"};
Is this what you are looking for?
You can initialize static non scalar members, but this must be done outside the class:
#include <string>
class RestaurantCheck{
static const int MENU_LENGTH = 3;
static const std::string menu[MENU_LENGTH];
};
const std::string RestaurantCheck::menu[RestaurantCheck::MENU_LENGTH] = {"Gumbo", "Shrimp", "Jar" };
note the "init line" must be present only in one file, best place is some .cpp file that is compiled to object. Here is what I mean:
restaurantcheck.h - RestaurantCheck header
restaurantcheck.cpp - RestaurantCheck implementation (best place for "init line")
main.cpp - program (where main() is located)

C++ Can't access public variable between classes

I've been trying desperately to get share a public variable between two classes in C++, but I can't seem to get the hang of it. I've tried getters and setters and calling it directly as a static variable but nothing.
This is what I've tried:
DataGrabber.h
#pragma once
class DataGrabber {
public:
static float temp;
void readProcess(){
temp = 1.2;
}
}
Particle.h
#pragma once
class Particle {
public:
void update() {
float x = DataGrabber::temp;
}
AND THEN THIS:
DataGrabber.h
#pragma once
class DataGrabber {
public:
float temp;
float get(){return temp;}
void readProcess(){
temp = 1.2;
}
}
Particle.h
#pragma once
class Particle {
public:
void update() {
float x = DataGrabber.get();
}
They are both being #include in another main header, testApp.h.
What is the exact problem? How do you use these classes?
Regardless, there are several problems with your getter code.
First, why do you use getter if you make the variable public? If you are going for this design, you should hide the variable as private, to protect it from direct modification.
Second, if it is a simple member variable, you should access it through an object that you pass to your function:
void update(DataGrabber& grabber) {
float x = grabber.get();
}
In this case, you would have to create this object in your main code, which you have not shown.
If you want to use a static variable instead, take a look at a Singleton pattern, but I would advise against it unless there are no better options for your exact problem.
Finally, you should #include all direct dependencies in your header files. Your Particle depends on DataGrabber, so you should include its header from Particle.h. Or, at least, you should add a forward declaration.

How to make a constant or variable accessible in entire program

I would like to have access to constant/variable of desktop width and height in entire program.
This is how I do it - add this code to every .h file of my program and then use it normally.
#include <QDesktopWidget>
QDesktopWidget desktop;
int desktopHeight = desktop.geometry().height();
int desktopWidth = desktop.geometry().width();
I know it is not a good way how to do it. I tried to make one special desktopSize.h and then include to required parts of my program. But I was not successful.
What should be in header file like this one which I need?
You really do not want to use that particular approach and include that code in all translation units. If you did each one would include two variables named desktopWidth and desktopHeight causing duplicate symbol errors during link time. It will also make it difficult to manage updating them if the size of the desktop changes after the application starts. If you really want to provide global variables holding the size of the desktop you should place them in a single .cpp file and place extern declarations in a single header file that is included when needed.
Header file (GlobalDesktopInfo.h)
#ifndef GLOBALDESKTOPINFO_H
#define GLOBALDESKTOPINFO_H
extern int desktopHeight;
extern int desktopWidth;
#endif GLOBALDESKTOPINFO_H
Source file (GlobalDesktopInfo.cpp)
#include "GlobalDesktopInfo.h"
int desktopHeight = 0;
int desktopWidth = 0;
You will also need to initialize it at the earlier point reasonably possible. I suggest doing this in your main() function.
#include "GlobalDesktopInfo.h"
// other includes
int main()
{
QApplication app;
QDesktopWidget desktop;
desktopHeight = desktop.geometry().height();
desktopWidth = desktop.geometry().width();
// other code and initialization
}
I think it's better to have some slots in a class which return the desired values and use Qt's Signal/slot mechanism to access them from other classes.
Just make a signal in the target class, connect it to a slot in the class containing the slots and make a connection between two objects of the classes. This way you can access them in every class you like by connecting a signal to a slot returning that value and just emitting the signal and getting the returned value.
For example you can have a class like :
class DesktopInformation
{
Q_OBJECT
public:
DesktopInformation(QObject *parent = 0);
~DesktopInformation();
QDesktopWidget desktop;
public slots:
int getWidth()
{
return desktop.geometry().width();
}
int getHeight()
{
return desktop.geometry().height();
}
};
And access the desktop information from any other class like :
class SomeClass: public QObject
{
Q_OBJECT
public:
SomeClass(QObject *parent = 0);
~SomeClass();
signals:
int getWidth();
int getHeight();
private:
void someFunction()
{
int width = getWidth();
int heigth = getHeight();
...
}
};
And connect the signal from an object of SomeClass to the slot in an object of DesktopInformation :
connect(someClass, SIGNAL(getWidth()), desktopInformation, SLOT(getWidth()));
In class someClass you can access the value returned from getWidth slot in desktopInformation by just calling the signal and using the returned value.
Note that the two objects should be in the same thread for this to work. If they are in different threads then the connection type should be of type Qt::BlockingQueuedConnection :
connect(someClass, SIGNAL(getWidth()), desktopInformation, SLOT(getWidth()), Qt::BlockingQueuedConnection);
Another way is two use static member functions but it is not recommended unless you have a good reason to do it :
class desktopInformation {
public:
static QDesktopWidget desktop;
static int getWidth()
{
return desktop.geometry().width();
}
static int getHeight()
{
return desktop.geometry().height();
}
};
class someClass {
public:
void do_something();
};
You can access desktopInformation's static member function from someClass like this:
void someClass::do_something()
{
int width = A::getWidth();
...
};