C++ 如何为双指针创建getter函数?

C++ 如何为双指针创建getter函数?,c++,pointers,C++,Pointers,我需要修改一个开源项目,以防止重用代码(创建GetGameRulesPtr()函数比继续进入引擎检索代码更有效。问题是,它存储为void**g_pGameRules。我从来没有真正理解指针指向指针的概念,我有点困惑 我正在创建一个GetGameRules()函数来检索这个指针,但是我不确定我的getter函数是否应该是void*ret-type然后返回*g_pGameRules,或者我应该如何进行操作。我现在正在讨论指针的用法,但我想找到合适的方法来学习 下面是代码,第58-89行是从游戏引擎检

我需要修改一个开源项目,以防止重用代码(创建GetGameRulesPtr()函数比继续进入引擎检索代码更有效。问题是,它存储为void**g_pGameRules。我从来没有真正理解指针指向指针的概念,我有点困惑

我正在创建一个GetGameRules()函数来检索这个指针,但是我不确定我的getter函数是否应该是void*ret-type然后返回*g_pGameRules,或者我应该如何进行操作。我现在正在讨论指针的用法,但我想找到合适的方法来学习

下面是代码,第58-89行是从游戏引擎检索g_pGameRules指针的SDK函数。其他函数是我要添加getter函数的

// extension.cpp

class SDKTools_API : public ISDKTools
{
public:
    virtual const char *GetInterfaceName()
    {
        return SMINTERFACE_SDKTOOLS_NAME;
    }

    virtual unsigned int GetInterfaceVersion()
    {
        return SMINTERFACE_SDKTOOLS_VERSION;
    }

    virtual IServer *GetIServer()
    {
        return iserver;
    }

    virtual void *GetGameRules()
    {
        return *g_pGameRules;
    }
} g_SDKTools_API;

// extension.h

namespace SourceMod
{
    /**
     * @brief SDKTools API.
     */
    class ISDKTools : public SMInterface
    {
    public:
        virtual const char *GetInterfaceName() = 0;
        virtual unsigned int GetInterfaceVersion() = 0;
    public:
        /**
         * @brief Returns a pointer to IServer if one was found.
         *
         * @return          IServer pointer, or NULL if SDKTools was unable to find one.
         */
        virtual IServer* GetIServer() = 0;

        /**
         * @brief Returns a pointer to GameRules if one was found.
         *
         * @return          GameRules pointer, or NULL if SDKTools was unable to find one.
         */
        virtual void* GetGameRules() = 0;
    };
}

// vglobals.cpp

void **g_pGameRules = NULL;
void *g_EntList = NULL;


void InitializeValveGlobals()
{
    g_EntList = gamehelpers->GetGlobalEntityList();

    char *addr;

#ifdef PLATFORM_WINDOWS
    /* g_pGameRules */
    if (!g_pGameConf->GetMemSig("CreateGameRulesObject", (void **)&addr) || !addr)
    {
        return;
    }

    int offset;
    if (!g_pGameConf->GetOffset("g_pGameRules", &offset) || !offset)
    {
        return;
    }
    g_pGameRules = *reinterpret_cast<void ***>(addr + offset);
#elif defined PLATFORM_LINUX || defined PLATFORM_APPLE
    /* g_pGameRules */
    if (!g_pGameConf->GetMemSig("g_pGameRules", (void **)&addr) || !addr)
    {
        return;
    }
    g_pGameRules = reinterpret_cast<void **>(addr);
#endif
}
//extension.cpp
类SDKTools\u API:公共ISDKTools
{
公众:
虚拟常量char*GetInterfaceName()
{
返回SMINTERFACE\u SDKTOOLS\u NAME;
}
虚拟无符号int-GetInterfaceVersion()
{
返回SMINTERFACE\u SDKTOOLS\u版本;
}
虚拟IServer*GetIServer()
{
返回iserver;
}
虚拟空间*GetGameRules()
{
返回*g_pGameRules;
}
}g_SDKTools_API;
//分机.h
命名空间SourceMod
{
/**
*@brief-SDKTools-API。
*/
类ISDKTools:publicsiminterface
{
公众:
虚拟常量char*GetInterfaceName()=0;
虚拟无符号int-GetInterfaceVersion()=0;
公众:
/**
*@brief返回指向IServer的指针(如果找到)。
*
*@返回IServer指针,如果SDKTools找不到,则返回NULL。
*/
虚拟IServer*GetIServer()=0;
/**
*@brief返回一个指向游戏规则的指针(如果找到)。
*
*@return GameRules指针,如果SDKTools找不到指针,则返回NULL。
*/
虚拟void*GetGameRules()=0;
};
}
//vglobals.cpp
void**g_pGameRules=NULL;
void*g_EntList=NULL;
void InitializeValveGlobals()
{
g_EntList=gamehelpers->getglobalentylist();
char*addr;
#ifdef平台\u窗口
/*g_PGA规则*/
如果(!g_pGameConf->GetMemSig(“CreateGameRulesObject”,(void**)和addr)| |!addr)
{
返回;
}
整数偏移量;
如果(!g_pGameConf->GetOffset(“g_pGameRules”,&offset)| |!offset)
{
返回;
}
g_pGameRules=*重新解释铸造(添加+偏移);
#elif定义的平台_LINUX | |定义的平台_APPLE
/*g_PGA规则*/
如果(!g_pGameConf->GetMemSig(“g_pGameRules”,(void**)和addr)| |!addr)
{
返回;
}
g_pGameRules=重新解释铸造(addr);
#恩迪夫
}

我认为它不是一个双指针,而是指向指针的指针,是的,如果你想得到void*你必须返回*g_pGameRules


我的想法是,指针就像级别一样。你必须显示你想要获得的级别。

我认为这不是双指针,而是指向指针的指针,是的,如果你想要获得void*你必须返回*g_pGameRules


我们的想法是,指针类似于级别。您必须显示您想要获得的级别。

如果您想要更改指针(例如,如果内存耗尽,则指向更大的内存块),则指向指针的指针非常有用,但要在项目移动的任何位置保留对该项目的公共引用

如果你不打算重新定位或移动指向的块,那么像你在吸气剂中的DeleFeReNigg一样好。我没有看过你正在使用的库,但是有一件事要考虑的是,当你得到一个实例时,它可以进行引用计数,以确保在得到指针之后对象没有被改变。 因此,我建议您查看库中是否有创建函数的“工厂”函数或“实例”并使用它们


-Dan8080

如果您希望更改指针(例如,如果内存耗尽,则指向更大的内存块),则指向指针的指针非常有用,但无论项目移动到哪里,都要保留对该项目的公共引用

如果你不打算重新定位或移动指向的块,那么像你在吸气剂中的DeleFeReNigg一样好。我没有看过你正在使用的库,但是有一件事要考虑的是,当你得到一个实例时,它可以进行引用计数,以确保在得到指针之后对象没有被改变。 因此,我建议您查看库中是否有创建函数的“工厂”函数或“实例”并使用它们


-Dan8080

您希望返回一个
void*
,并在实现代码中对相应的
SomeType**
进行强制转换。这是因为
void**
具有奇怪的语义(我现在在谷歌上找不到)。它还告诉用户比他们真正需要的更多的信息。使用
void*
一开始就是为了避免向用户提供他们不需要的信息

如果这是一个选项,我个人建议完全避免使用
void*
,只需为它们提供一个不透明的引用类型来调用您的API;,并向用户传回一个
GameObjectRef*
,该指针由系统实际使用的任何指针铸造而成。这允许用户编写强类型代码,因此他们不会像使用
void*
时那样意外地向函数提供错误的指针类型

指针(以及指向指针的指针)的工作方式:

想象一下,你问我你姑妈住在哪里。然后,我递给你一张有地址的纸。那张纸是一个指向房子的指针

现在,把那张写有地址的纸拿起来,用数码相机拍张照片,然后把照片放到你的个人维基网站上