c++ - Passing pointers to different variable types to a function and reuse them later for assignmet -


in gui based project need page1 mark variable to changed , call page2, page2 reads user's input , updates marked variable new value. variable type different , variables held external linked library.

how achieve without creating fname_uint8, fname_uint16, fname_giventype variants markers , setters?

this example sums scenario:

there varholder class holds lot of structs lot of variables, e.g.:

class varholder  { public:     typedef struct {         int8_t var1;         int16_t var2;         int32_t var3;         char str1[40];         float var4;     } struct1_t;     /* ...continues... */  struct1_t struct1; } 

now class firststage wants mark 1 variable change, , calls member of committer_instance instance of class committer

class firststage  {     /* ... */     void dofirststage(void)     {         /* globally defined committer instance */         g_committer_instance->mark_var_change(&varholder_instance->struct1.var1);     } } 

committer::mark_var_change(t*) defined follows:

template <typename t> void committer::mark_var_change(t *var) {     /* store pointer variable */     /* save somewhere preserving type */ = var; } 

a member of secondstage, finally, wants use available value update variable marked change through same g_committer_instance, this:

class secondstage {     /* ... */     template <typename t>     void dosecondstage(t new_value)     {         g_committer_instance->commit_change(new_value);     } } 

where committer::commit_change(t) defined follows:

template <typename t> void committer::commit_change(t new_value) {     /* dereferencing stored pointer */     *(/*whatever stored before*/) = new_value; } 

of course not able realize type-indipendent "marker , retriever" can seamlessy update variable based upon address. suggestion appreciated.

mcve

### varholder.h #include <stdint.h> class varholder { public: varholder() {} virtual ~varholder() {} typedef struct  { int8_t var1; uint8_t var2; int64_t var3; char str1[40]; } struct1_t;  struct1_t struct1; }  ### firststage.h #include global.h  class firststage  {     public:     firststage() {}     ~firststage() {}      void dofirststage(void)     {         /* globally defined committer instance */         g_committer_instance->mark_var_change(&varholder_instance->struct1.var1);     } }  ### secondstage.h #include global.h  class secondstage {     public:     secondstage() {}     ~secondstage() {}     template <typename t>     void dosecondstage(t new_value)     {         g_committer_instance->commit_change(new_value);     } } ### committer.h #include global.h  class committer {     public:     committer() {}     ~committer() {} template <typename t> void committer::mark_var_change(t *var) {     /* store pointer variable */     /* save somewhere preserving type */ = var; }  template <typename t> void committer::commit_change(t new_value) {     /* dereferencing stored pointer */     *(/*whatever stored before*/) = new_value; } }   ### global.h  #include varholder.h #include committer.h  extern committer *g_committer_instance; extern varholder *varholder_instance;  ### main.cpp  #include global.h #include varholder.h #include firststage.h #include secondstage.h   committer *g_committer_instance; varholder *varholder_instance;  int main()  { g_committer_instance = new committer(); varholder_instance = new varholder(); firststage *fstage = new firststage(); secondstage *sstage = new secondstage();  int8_t var_new = 100;  /* first stage */ fstage->dofirststage(); /* second stage */ sstage->dosecondstage(var_new);  return 0; } 

you may use void* without (unsafe) or typeid:

class committer { public:       template <typename t>     void mark_var_change(t *var)     {         mpointer = var;         mtypeinfo = &typeid(t*);     }      template <typename t>     void commit_change(t new_value)     {         if (*mtypeinfo != typeid(t*)) {             throw std::runtime_error("bad type");         }         if (mpointer == nullptr) {             throw std::runtime_error("nullptr stocked");         }         *reinterpret_cast<t*>(mpointer) = new_value;     }  private:     void* mpointer = nullptr;     const std::type_info* mtypeinfo = nullptr; }; 

or safer boost::any manage type:

class committer { public:       template <typename t>     void mark_var_change(t *var)     {         mpointer = var;     }      template <typename t>     void commit_change(t new_value)     {         t* pointer = boost::any_cast<t*>(mpointer); // throw bad type         if (pointer == nullptr) {             throw std::runtime_error("nullptr stocked");         }         *pointer = new_value;     }  private:     boost::any mpointer; }; 

live example


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -