I'd like to have 2 different Data instances used in the client without either changing the static key in its member or resetting its member's value.
struct Data
{
static std::vector<int> vi;
};
struct DataUser
{
DataUser(int s) {
for (int i = 0; i < s; ++i)
{
Data::vi.emplace_back(i);
}
}
int getSize() { return Data::vi.size(); }
};
std::vector<int> Data::vi(0);
//.............. use it
int main()
{
{
DataUser d1(5);
std::cout << d1.getSize() << "\n";
}
{
DataUser d2(10);
std::cout << d2.getSize() << "\n";
}
}
e.g the output of the program is
5
15
I'd like it to be
5
10
static always means there is only one single instance of it in one binary.
The only way to have separate instances is to have a Data member and non static member in Data.
Related
void ZMDAggregator::getMZMap(DataModel::MZMap &mZM)
{
LOGGER_EVENT("ZMDAggregator getMZMap()");
std::unique_lock<std::mutex> lockSlot(internalStateMutex);
mZM.clear();
mZM = this->mZM;
}
void ZMDAggregator::Roscallback(const ros::MZMap msgMZMap)
{
std::unique_lock<std::mutex> lockSlot(internalStateMutex);
MZMap map;
for( auto const & entry : msgMZMap.m_z_e)
{
mzEntry.clear();
mzEntry.mID = entry.mID;
mzEntry.tMode = entry.tMode;
mzEntry.areaID = entry.areaID;
mzEntry.oZone = entry.oZone;
mzEntry.authZ = entry.authZ;
mzEntry.blockZ = entry.blockZ;
map.mzEntry.push_back(mzEntry);
}
}
The above function gets called around 30 times a second.This is causing a high cpu utilization in my program.
struct MZEntry
{
uint32_t mID;
bool tMode;
uint32_t areaID;
uint32_t oZone;
using ZList = std::vector<uint32_t>;
ZList authZ;
ZList blockZ;
};
struct MZMap
{
std::vector<MZEntry> mzEntry;
}
Class ZMDAggregator {
mutable std::mutex internalStateMutex;
MZMap mzMap;
}
My question is if I convert getMZMap() to accept a shared_ptr instead of a reference and also change the type of the member variable mzMap to a shared_ptr as shown below.
void ZMDAggregator::getMZMap(std::shared_ptr<DataModel::MZMap> &mZM)
{
LOGGER_EVENT("ZMDAggregator getMZMap()");
std::unique_lock<std::mutex> lockSlot(internalStateMutex);
mZM = this->mZM;
}
Class ZMDAggregator {
mutable std::mutex internalStateMutex;
std::shared_ptr<DataModel::MZMap> mzMap;
}
My question is as follows.
My class ZMDAggregator updates the structure once every 50 milliseconds, so around 20 times a second As you can see this happens inside the unique_lock.
The Thread that calls, getMZMap() calls it around 20 times a second.
By modifying initial structure to a shared_ptr, I should be able to bring down CPU cycles, as a struct copy is now avoided. However now since the same pointer is being accessed in the caller thread (Reader)
there is a risk that I can get half an old pointer and half a new pointer when the function Roscallback updates the structure.
Without using a mutex, (These two functions are two separate classes) is there a way to ensure that the above scenario doesn't occour ?
As per the suggestion of #freakish, I have returned shared_ptr by value. Please find the code below.
#include <iostream>
#include <memory>
#include <vector>
struct MZEntry
{
uint32_t mID;
bool tMode;
uint32_t areaID;
uint32_t oZone;
using ZList = std::vector<uint32_t>;
ZList authZ;
ZList blockZ;
};
struct MZMap
{
std::vector<MZEntry> mzEntry;
};
class A
{
public:
void populate()
{
std::cout << "A populate()" << std::endl;
MZEntry mzEntry;
mzEntry.mID = 55;
mzEntry.tMode = true;
mzEntry.areaID = 55;
mzEntry.oZone = 55;
mzEntry.authZ = {1,2,3};
mzEntry.blockZ = {4,5,6};
l->mzEntry.push_back(mzEntry);
}
std::shared_ptr<MZMap> assign() const
{
return l;
}
std::shared_ptr<MZMap> l;
A()
{
std::cout << "A constructor()" << std::endl;
l = std::make_shared<MZMap>();
populate();
}
};
class B
{
public:
B()
{
std::cout << "B constructor" << std::endl;
a = new A();
}
void getValue()
{
std::cout << "B getValue()" << std::endl;
p3 = a->assign();
}
void print()
{
std::cout << "machineID: " << p3->mzEntry[0].mID << std::endl;
}
std::shared_ptr<MZMap> p3;
A *a;
};
int main() {
B *b = new B();
b->getValue();
b->print();
return 0;
}
So what you are saying is in the line
p3 = a->assign();
It doesn't do a struct copy, instead it just increments the reference count? Is my understanding correct?
I want to count ascending and descending data for each created object.But I can't handle it separately because the 2 objects I created also use the same static variable.The codes are as follows, How do I have to make changes.
void MyObject::handle_receive(std::size_t length) {
getIncrementCount()++;
if(some-condition)
{
getIncrementCount() = 0;
getDecreaseCount() = 0;
}
}
void MyObject::handle_timeout() {
getDecreaseCount()++;
if(some-condition)
{
getIncrementCount() = 0;
getDecreaseCount() = 0;
}
}
int & MyObject::getDecreaseCount()
{
static int theCount = 0;
return theCount;
}
int & MyObject::getIncrementCount()
{
static int theCount = 0;
return theCount;
}
main()
{
for (size_t i = 0; i < SensorSettingsList.size(); i++) {
try {
MyObject *ipPingReporter = new MyObject(io_service, SensorSettingsList.at(i).biosName);
}
catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
}
Please revisit the meaning of static. It is exactly the opposite of what you want - it is a variable that is shared between all objects of the same type.
For keeping state in an object, you need to make the variable part of the class, not of the function:
class MyObject {
int incrementCount;
void increment() {
++incrementCount;
}
int getIncrementCount() {
return incrementCount;
}
};
(I implemented the methods within the class for brevity. You can continue to implement them in void MyObject::increment, which is arguably better.)
Other than that (somewhat unrelated to your question), I would suggest that you do not return references to those variables. You do not want an outside class to modify the value. Right now, in your code, there is nothing that keeps me from messing up the counts by calling someObject.getIncrementCount() = 15.
I have a struct with two members, for example:
struct DataSet {
int x;
int y;
};
..., and i have to access those in a method, but only one at a time, for example:
void foo(StructMember dsm) { // ("StructMember" does not exist)
DataSet ds;
ds.x = 4;
ds.y = 6;
std::cout << ds.dsm * ds.dsm << std::endl;
}
foo(x);
foo(y);
Output i wish to have:
16
36
What should I do when I have to solve a problem like this? Is there a data type which can access a member?
Yes, you can use a pointer-to-member. The syntax for the type is TypeOfMember TypeOfStruct::*, and to access you do struct_variable.*pointer_variable
using StructMember = int DataSet::*; // Pointer to a member of `DataSet` of type `int`
void foo(StructMember dsm) {
DataSet ds;
ds.x = 4;
ds.y = 6;
std::cout << ds.*dsm * ds.*dsm << std::endl;
}
int main() {
foo(&DataSet::x);
foo(&DataSet::y);
}
I am having trouble in initializing an array of structures with a function pointer as a member in it.
class Record
{
private:
typedef void (*display_fn_t) ();
struct record {
int a;
display_fn_t disp;
};
static const record rec[];
void disp1() { cout << "Display 1 with a string to display" << endl; }
void disp2() { cout << "Display 2 with an integer to display" << endl; }
public:
int find() { /* logic to find the record comes here */ }
void display() {
for (int i = 0; i < 2; i++) {
rec[i].disp();
}
}
}
const Record::record Record::rec[] = {
{ 10, disp1 },
{ 11, disp2 }
};
int main()
{
Record r;
if (r.find())
r.display();
return 0;
}
When I compile the above code, I am getting the following compilation error:
mca_record.cpp:56: error: argument of type ‘void (Record::)()’ does
not match ‘void (*)()’
Your syntax is wrong and isn't using the appropriate operators.
Fixing a multitude of syntax errors, and stripping out the unrelated find operation, then utilizing proper member function pointers and operator ->* gives the following (one of several ways to do this):
#include <iostream>
class Record
{
private:
typedef void (Record::*display_memfn_t)();
struct record
{
int a;
display_memfn_t disp;
};
static const record rec[];
void disp1() { std::cout << "Display 1 with a string to display" << std::endl; }
void disp2() { std::cout << "Display 2 with an integer to display" << std::endl; }
public:
void display();
};
const Record::record Record::rec[] =
{
{ 10, &Record::disp1 },
{ 11, &Record::disp2 }
};
void Record::display()
{
for (size_t i=0; i<sizeof rec/sizeof*rec; ++i)
(this->*(rec[i].disp))();
}
int main()
{
Record r;
r.display();
return 0;
}
Output
Display 1 with a string to display
Display 2 with an integer to display
Compare it to your existing code, and not in particular that pointers to member functions are not simply pointers to functions. They require different handling and generally different operators to utilize. See here for different methods of member access (both variable and function).
Best of luck.
To make the call work you must invoke it like this:
for (int i = 0; i < 2; i++) {
(*rec[i].disp)();
}
And initialize the table this way:
const Record::record Record::rec[] = {
{ 10, &Record::disp1 },
{ 11, &Record::disp2 }
};
The first time the function is called it returns 1. Every other time it's called it returns 1+the number returned the last time it was called.
int counter()
{
return counter()++;
}
Is this valid?
Sounds like you want a static variable:
int counter()
{
static int count = 0; // initialized only once across all calls
return ++count;
}
You can use static.
int counter()
{
static int counter = 0;
return ++counter;
}
Static (in the function body context) is just a nice keyword that makes a variable essentially global, but not semantic-wise. So you cannot use it outside of the function, but it gets initialized with all the globals (it means once near the start point) and it is stored where other global variables are.
Just for the record, since c++ label. You could write a functor class, with a private count variable and overload operator(). Or even probably a template that would be able to wrap any function and count its calls.
Also note that in your try, you call counter recursively with no exit point with a fixed value. It will never finish (unless you count stack overflowing as end).
Apart from defining a static local variable in the function as it was already shown you can define a static class member function that will increment a static data member of the same class. For example
#include <iostream>
class Counter
{
public:
static int Count() { return ( ++cnt ); }
static int Reset() { return ( cnt = 0 ); }
private:
static int cnt;
};
int Counter::cnt = 0;
int main()
{
for ( int i = 0; i < 10; i++ ) std::cout << Counter::Count() << ' ';
std::cout << std::endl;
std::cout << "\nResetting the counter to " << Counter::Reset() << std::endl;
for ( int i = 0; i < 10; i++ ) std::cout << Counter::Count() << ' ';
std::cout << std::endl;
}
If using C++11, use a std::function and a mutable lambda expression:
#include <iostream>
#include <functional>
using namespace std;
int main()
{
function<int()> func = [&]()
{
static int i = 1;
return i++;
};
for(int i = 0; i < 10; i++)
cout << func() << endl;
return 0;
}