J'ai créé une classe A qui a besoin d'une ressource r commune à toutes les instances, dans un projet multithread. Cette ressource est coûteuse en cpu pour être construite, et aussi en mémoire.

J'ai donc mis cette ressource dans une classe à part, et je la construit dans le constructeur de A, à l'aide de std::call_once :

A.cpp

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <mutex>          // std::call_once, std::once_flag
#include <new>
 
std::once_flag A::is_R_CTORed, A::is_R_DTORed;
R* A::r;
size_t A::Qt = 0;
 
A::A()
{
    std::call_once(is_R_CTORed, [&]{
        r = new R();
    });
    Qt++;
}
 
A::~A() {
    Qt--;
    if (!Qt) {
        std::call_once(is_R_DTORed, [&]{
            delete r;
        });
    }
}
Mais cette construction n'est pas satisfaisante, car si dans l'applicatif, j'ai une transition avec zéro instances de la classe A, alors la ressource r est détruite, et n'est pas reconstruite lorsqu'une nouvelle instance de A est créée, à cause du call_once.

J'aurais bien aimé pouvoir réinitialiser le std::once_flag A::is_R_CTORed dans le destructeur de A, et le std::once_flag A::is_R_DTORed dans le constructeur de A, ce qui aurait fait un hystérésis robuste je pense.

  1. Peut-on réinitialiser un std::once_flag ? apparemment non ?
  2. La ressource r étant propre à la classe A, la gérer à l'extérieur n'est pas très satisfaisant ?
  3. Je peux aussi ajouter une méthode à la classe A pour détruire la ressource r, à la fin de l'application ?
  4. Quelle est la mailleure façon de faire svp ?