В проекте на основе графического интерфейса мне нужно Page1 отметить переменную , которую нужно изменить и вызвать страницу2, Страница2 читает ввод пользователя и обновляет отмеченную переменную с помощью новое значение. Тип переменной всегда разный, и все переменные хранятся во внешней связанной библиотеке.Передача указателей на различные типы переменных на функцию и их повторное использование для присваивания
Как достичь этого без создания fname_uint8, fname_uint16, fname_giventype вариантов для маркеров и сеттеров?
Этот пример подводит итог сценария:
Там является VarHolder
класс, который имеет много структур с большим количеством переменных, например:
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;
}
Теперь класс FirstStage
хочет отметьте одну переменную для изменения и называет элемент экземпляра committer_instance
класса 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*)
определяется следующим образом:
template <typename T>
void Committer::mark_var_change(T *var)
{
/* Store a pointer to the variable */
/* SAVE SOMEWHERE PRESERVING TYPE */ = var;
}
Член SecondStage
, наконец, хочет использовать в настоящее время доступное значение для обновления переменной помеченный для изменения через тот же g_committer_instance
, как это:
class SecondStage
{
/* ... */
template <typename T>
void doSecondStage(T new_value)
{
g_committer_instance->commit_change(new_value);
}
}
, где Committer::commit_change(T)
определяется следующим образом:
template <typename T>
void Committer::commit_change(T new_value)
{
/* Dereferencing the previously stored pointer */
*(/*WHATEVER I STORED BEFORE*/) = new_value;
}
Конечно, то, что я не могу сделать, это реализовать независимый от типа «маркер и ретривер», который может легко обновлять переменную на основе их адреса. Любое предложение очень ценится.
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 a pointer to the variable */
/* SAVE SOMEWHERE PRESERVING TYPE */ = var;
}
template <typename T>
void Committer::commit_change(T new_value)
{
/* Dereferencing the previously stored pointer */
*(/*WHATEVER I 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;
}
Вы можете посмотреть на 'повысить :: any'. – Jarod42
Создайте [MCVE] (http://stackoverflow.com/help/mcve), который описывает вашу проблему. – TobiMcNamobi
Есть только одна переменная для каждого типа в 'struct1_t'? Если да, почему бы не использовать союз? Кроме того, каково будет поведение, если тип 'new_value' не конвертируется в' varholder_instance-> struct1.var1' –