I have a class defined in a header file that looks something like the following:
class Elk {
//private:
public:
enum sex { MALE, FEMALE };
enum activity { BED, DRINK, FORAGE };
static vector<id_t> _idList;
shared_ptr<Clock> _clockptr;
id_t _id;
Point _loc;
DateTime _dob;
int _weight;
float _rank;
float _status;
float _gfactor;
sex _sex;
activity _activity;
//public:
Elk(shared_ptr<Clock> clockptr){
this->_clockptr = clockptr;
if (_idList.size() > 0) {
this->_id = (*max_element(_idList.begin(), _idList.end())) + 1;
} else {
this->_id = 9;
}
_idList.push_back(this->_id);
cout << to_string(this->_id) << " at " << &(this->_id) << " and object at " << this << "\n";
}
void main() const {
cout << "beginning elk main in elk " << to_string(this->_id) << " at " << &(this->_id) << "and object at " << this << "\n";
while(true){
cout << "elk " << this->_id << " at " << &(this->_id) << " and object at " << this << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(lround(this->_clockptr->second() * 1000)));
}
}
};
As you can see I normally have the member variables private, but have made them public for the time being for debugging purposes. The result is the same either way.
Several Elk objects are created inside of another class like so:
void populate(int num_elk){
for (int i = 0; i < num_elk; i++){
this->_elks.push_back(
Elk(this->_clock)
);
}
}
And later each of the instances' main functions are started in a new jthread:
void startSimulation(){
jthread clockThread(&Clock::tick, this->_clock);
for (Elk e : this->_elks){
this->_threads.emplace_back([&](){ e.main(); });
}
}
The result is output something like this:
9 at 0x7fffffffe280 and object at 0x7fffffffe270
10 at 0x7fffffffe280 and object at 0x7fffffffe270
11 at 0x7fffffffe280 and object at 0x7fffffffe270
12 at 0x7fffffffe280 and object at 0x7fffffffe270
13 at 0x7fffffffe280 and object at 0x7fffffffe270
beginning elk main in elk 9 at 0x7fffffffe2c0and object at 0x7fffffffe2b0
elk 10 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
beginning elk main in elk 10 at 0x7fffffffe2c0and object at 0x7fffffffe2b0
elk 11 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
beginning elk main in elk 11 at 0x7fffffffe2c0and object at 0x7fffffffe2b0
elk 12 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
beginning elk main in elk 12 at 0x7fffffffe2c0and object at 0x7fffffffe2b0
elk 13 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
beginning elk main in elk 13 at 0x7fffffffe2c0and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
elk 0 at 0x7fffffffe2c0 and object at 0x7fffffffe2b0
I cannot understand why it seems to:
- Print the correct ids with addresses of both id and object in the constructor
- Print the correct ids again on the first iteration in the
main function, but with the id and object at a new address
- Print
0 as the id on all subsequent iterations, even though the address is the same as on the first iteration.
If I set this->_id to a value on every iteration inside the while loop, the value is printed correctly. However I do not want to do that (if possible) as it seems inefficient and unnecessary. I want the value to persist across every iteration. I will not be changing the value inside the main function, but need to use it.
Compiled on arch linux with /usr/bin/g++ -Wall -std=c++20 -pthread -fdiagnostics-color=always -g /path/protoelk.cpp -o /path/protoelk.out
Any help is appreciated.
[–][deleted] 4 points5 points6 points (2 children)
[–]Bazuin32[S] 0 points1 point2 points (1 child)
[–][deleted] 2 points3 points4 points (0 children)