jeudi 14 avril 2022

Elegant/efficient way to have objects survive their scope

I'm working with an API that has the form:

void setup() { 
  //.. 
}
void render() {
  //.. 
}
void clean_up() {
 //..
}

I'm trying to figure what is the most elegant, thread-safe and efficient way to have a persistent class C consume instances of class B that internally refer to memory demanding instances of class A. What I am currently doing is along these lines:

C global_c_obj;

void setup() { 
  auto b_obj {std::make_shared<B>()}; // b_obj is parametrised in the actual code
  global_c_obj.push_back(b_obj); // so that b_obj will survive this scope
}

void render() {
  // every several cycles func() is called in a new thread 
  auto results = global_c_obj.get_results(); 
  // do work with results
}

void func() {
  auto new_b_obj {std::make_shared<B>()}; // new object with new parameters
  global_c_obj.push_back(new_b_obj); 
}

With class B having the form:

class B {
private: 
  std::shared_ptr<A> memory_intensive_obj;
  // .. 
public:
  // ... 
};

There two things I don't like in this approach but I can't think of a better way at the moment:

  1. The object of type C is a global one, and I'd rather not use globals at all
  2. C's pubic interface is made so as to expect std::shared_ptr<B> as arguments, while I'd much rather prefer an interface expecting B* or const B& so that I could use the same interface in different contexts and with different APIs.

As for point 2. above, and since B already holds a std::shared_ptr<A> so that it is not particularly large as an object, I could simply pass B by value to C. But B is still larger than std::shared_ptr<B> and I think that it'd be more expensive to copy-construct rather than used a std::shared_ptr.

Any other tactics around such an architecture?

Aucun commentaire:

Enregistrer un commentaire