Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将指向不同变量类型的指针传递给函数,并在以后将其重新用于assignmet_C++_Variables_Templates_Pointers_Code Reuse - Fatal编程技术网

C++ 将指向不同变量类型的指针传递给函数,并在以后将其重新用于assignmet

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 {

在基于GUI的项目中,我需要Page1标记要更改的变量并调用Page2,Page2读取用户的输入并用新值更新标记的变量。 变量类型总是不同的,所有变量都由外部链接库保存

如何在不创建标记器和设置器的fname\u uint8、fname\u uint16、fname\u给定类型变体的情况下实现这一点?

此示例总结了该场景:

有一个
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;
};