I am still collecting my experience with C++ and I am currently biting my teeth with instanciating classes into a vector if the class contains a vector. Enviroment: Visual Studio 2019, so using latest (C++17).
Situation: I need to implement a data-holding class which:
-stores a data-tupel,
-need to store multiple instances of this class all containing different data (using a vector probably best),
-and read- and write-access needs to be thread-safe per data-instance.
Background is that one thread updates the data from another source and the second thread further modifies the data and generates output from it.
Schematic example code (the original code is still too messy):
// mutex_testing.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <mutex>
#include <vector>
using namespace std;
class Data {
public:
mutex update_block{};
void write_data(int data) {
unique_lock<mutex> lock{ update_block };
x = data;
}
int read_data() {
unique_lock<mutex> lock{ update_block };
return(x);
}
Data(int in) : x{ in } {};
private:
int x{ 0 };
};
int main() {
vector<Data> datastore{};
datastore.push_back(*new Data{ 1 });
datastore.push_back(*new Data{ 2 });
Data demo{ *new Data{3} };
datastore.emplace_back(4);
};
The class works fine without a mutex. However, as soon as I try to instanciate it with *new, it tries to copy the instance, which of course hits the deleted copy operator of mutex Same problem. How can I get something into the vector without somehow triggering a copy? I thought emplace_back was supposed to do only move?
//EDIT: I have worked through Stroustrups "Programming: principles and practice using C++" and are using also his main C++ reference Edition 4, if somebody wants to point me there, but all the threading examples and references are only using global mutex's, and from my understanding out of the reference my forced moves should work?!
//EDIT2: thanks for the first advices, regarding the pointer use, I will have to read again into unique_pointer referenced in How can I use something like std::vector<std::mutex>? . I will also try to post a reproducable example.
//EDIT3: now "running" code (except the mentioned problem), sorry for this. Regarding ressource allocation with the new: that was actually a question I had. I believed when I do:
datastore.push_back(*new Data{ 1 });
as soon as datastore goes out of scope, the destructor of vector is called, which shoud call the destructor of data, which should free the space allocated to x as I did not 'new' it in the class definition. Do I mess this up with my pushback-new?