将指向不同变量类型的指针传递给函数,并在以后的赋值中重用它们
Passing pointers to different variable types to a function and reuse them later for assignmet
在一个基于GUI的项目中,我需要Page1标记一个变量要更改并调用Page2, Page2读取用户的输入并使用新值更新标记的变量。变量类型总是不同的,并且所有变量都由外部链接库保存。
如何实现这一点,而不创建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
的committer_instance
实例的成员
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;
}
您可以单独使用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;
};
- 与类型id Live example
或更安全的boost::any
,它自己管理类型:
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;
};
生活例子
相关文章:
- 为"adjacent"变量赋值时出现问题
- 非常量变量只读位置的赋值
- 变量在使用赋值语句赋值后恢复为以前的值
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- 如何在 c++ 中正确声明/赋值变量的值
- 在未初始化的变量上使用复合赋值运算符(+=, ..)不是C++中的UB?
- c++问题:给一个变量赋值后,另一个变量发生了变化
- 如何在不使用赋值运算符的情况下为动态变量赋值?
- 为什么我不能为变量赋值函数?
- 可视化的c++变量赋值使代码正常工作
- 作为赋值(增加引用变量)C++的左操作数所需的左值
- 如何为结构类型变量赋值
- const变量是否可以在具有默认值的参数中赋值(作为可选参数)
- C++中重载复合赋值运算符不会更改变量
- 初始值设定项列表与构造函数赋值与变量定义
- 在结构的构造函数中使用类方法赋值变量
- 原子变量的多重赋值是原子操作吗?
- 在 If 语句 [C++] 中赋值变量
- 赋值变量时c++未处理异常访问冲突
- 使用reinterpret_cast赋值变量后可能的析构函数