C++ 将指向不同变量类型的指针传递给函数,并在以后将其重新用于assignmet
在基于GUI的项目中,我需要Page1标记要更改的变量并调用Page2,Page2读取用户的输入并用新值更新标记的变量。 变量类型总是不同的,所有变量都由外部链接库保存 如何在不创建标记器和设置器的fname\u uint8、fname\u uint16、fname\u给定类型变体的情况下实现这一点? 此示例总结了该场景: 有一个C++ 将指向不同变量类型的指针传递给函数,并在以后将其重新用于assignmet,c++,variables,templates,pointers,code-reuse,C++,Variables,Templates,Pointers,Code Reuse,在基于GUI的项目中,我需要Page1标记要更改的变量并调用Page2,Page2读取用户的输入并用新值更新标记的变量。 变量类型总是不同的,所有变量都由外部链接库保存 如何在不创建标记器和设置器的fname\u uint8、fname\u uint16、fname\u给定类型变体的情况下实现这一点? 此示例总结了该场景: 有一个VarHolder类,它保存了许多带有许多变量的结构,例如: class VarHolder { public: typedef struct {
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
实例的committer\u实例的成员
class FirstStage
{
/* ... */
void doFirstStage(void)
{
/* Globally defined committer instance */
g_committer_instance->mark_var_change(&varholder_instance->struct1.var1);
}
}
Committer::mark\u var\u change(T*)
定义如下:
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;
}
其中Committer::commit\u change(T)
的定义如下:
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;
}
模板
无效提交者::提交更改(T新值)
{
/*取消对以前存储的指针的引用*/
*(/*我之前存储的内容*/)=新的_值;
}
当然,我不能实现一个类型独立的“marker and retriever”,它可以根据seamlessy的地址更新变量。
非常感谢您的任何建议
MCVE
###varholder.h
#包括
类变容二极管
{
公众:
VarHolder(){}
虚拟~VarHolder(){}
类型定义结构
{
int8_t var1;
uint8_t var2;
int64_t var3;
char-str1[40];
}结构1;
结构1_t结构1;
}
###第一阶段
#包括global.h
第一阶段
{
公众:
第一阶段(){}
~FirstStage(){}
第一阶段无效(无效)
{
/*全局定义的提交者实例*/
g\u提交者\u实例->标记变量更改(&varholder\u实例->struct1.var1);
}
}
###第二阶段
#包括global.h
第二阶段
{
公众:
第二阶段(){}
~SecondStage(){}
模板
无效doSecondStage(T新值)
{
g_提交者_实例->提交_更改(新值);
}
}
###提交人
#包括global.h
班级提交人
{
公众:
提交者(){}
~Committer(){}
模板
无效提交人::标记变量更改(T*var)
{
/*存储指向变量的指针*/
/*保存类型*/=var;
}
模板
无效提交者::提交更改(T新值)
{
/*取消对以前存储的指针的引用*/
*(/*我之前存储的内容*/)=新的_值;
}
}
###全球
#包括varholder.h
#包括提交人
外部提交者*g_提交者_实例;
外部VarHolder*VarHolder\u实例;
###main.cpp
#包括global.h
#包括varholder.h
#包括第一阶段
#包括第二阶段
Committer*g_Committer_实例;
VarHolder*VarHolder_实例;
int main()
{
g_committer_instance=new committer();
varholder_实例=新的varholder();
FirstStage*fstage=新的第一阶段();
第二阶段*sstage=新的第二阶段();
int8_t var_new=100;
/*第一阶段*/
fstage->doFirstStage();
/*第二阶段*/
sstage->doSecondStage(新变量);
返回0;
}
您可以使用void*
而不使用(不安全)或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 was stocked");
}
*reinterpret_cast<T*>(mPointer) = new_value;
}
private:
void* mPointer = nullptr;
const std::type_info* mTypeInfo = nullptr;
};
您可以查看boost::any
。请创建一个描述您的问题的变量。在struct1\t
中,每种类型是否只有一个变量?如果是这样,为什么不使用工会呢?另外,如果new\u value
的类型不能转换为varholder\u instance->struct1.var1
@Component10不,每种类型的任何数字,那么会发生什么行为。该工具的用户必须检查可兑换性,不管怎样,强制转换是在编译时完成的。@TobiMcNamobi I根据请求添加了一个MCVE。我已经尝试了第一个解决方案,但在这种情况下,即使输入错误也会致命,覆盖结构的后续部分(如果幸运的话)…顺便问一下,是否存在非boost::any?到目前为止,boost是一个不可行的解决方案…@FrancisStraccia:void*
版本修改为使用typeid
检查类型。
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 with bad type
if (pointer == nullptr) {
throw std::runtime_error("nullptr was stocked");
}
*pointer = new_value;
}
private:
boost::any mPointer;
};