【问题标题】:C++ member function pointer use-case?C ++成员函数指针用例?
【发布时间】:2018-09-20 08:52:20
【问题描述】:

我一直在使用带有 2 个类的 C++ 在 OpenGL API 上编写一个小框架:

  • 游戏对象(组件架构):

    • 将 MeshRenderer 添加为组件。
    • 添加材料作为组件。
  • 材质:

    • 处理所有着色器数据,并作为组件附加到游戏对象。
    • 包含私有:void RegisterComponent(RCUpdateCallback& funcPtr);
  • 网格渲染器:

    • 处理分配的网格数据(VAO、VBO、EBO 等)

      // routine to handle shader change  
      Contains private: void MeshRenderer::UpdateMaterial();  
      

现在在运行期间,如果用户想要更改材质的着色器,那么网格类也需要使用新数据进行更新。所以我正在尝试在材质类中存储MeshRenderer::UpdateMaterial(SG_EUpdate& flag) -> 函数的回调。

这是它的伪代码:

/* Register the callback here for this mesh's Update method inside the constructor of the mesh*/
SGMeshRenderer::SGMeshRenderer( SGMeshFilter mesh_copy, SG_PTRS<SGMaterial> mat )
{
    SGUUIDGenerator::instance().Create( uuid );
    material = mat;
    material->RegisterComponent( this, &SGRenderer::UpdateMaterial );
}

/* Register Function inside the mesh class for storing all the callback */
void SGMaterial::RegisterComponent( SGRenderer* const object, RCUpdateMethod method )
{
    map_renderCompCallbacks.insert( MapRCUCallbacks::value_type( object, method ) );
}

/*   Whenever New Shader is set, material calls all the meshes UpdateMethod */
void SGMaterial::SetShader( SG_PTRS<Shader> const shader )
{
    activeShader = shader;
    std::cout << "START OF FUNCTION : " << __FUNCTION__ << std::endl;
    std::cout << "Material name : " << name << " id : " << uuid << "Active Shader : " << activeShader->shaderProgramName << std::endl;
    std::cout << "END OF FUNCTION : " << __FUNCTION__ << std::endl;
    // Generate Shader data
    SGMaterialManager::instance().Create( uuid, *activeShader );
    // Update all the RendererComponents using this material ( ReBuild- VAOs)
    for( auto it = map_renderCompCallbacks.begin(); it != map_renderCompCallbacks.end(); it++ )
    {
        // using Object reference to call the stored pointer.
        // If we have the object reference we can do it->first->UpdateMethod() directly.
        ( it->first->*it->second )( SG_EUpdateFlag::MaterialUpdate );
    }
}

问题是我可以将方法存储为回调,但是当从 Material 类调用方法时,我还需要网格对象的引用来调用相应的函数指针。

类似这样的:MeshRenderer::*StoredFuncPointer(args);

现在我看不出存储回调有什么意义,如果我们要发送对象引用,我可以通过引用调用所有方法。

如果我们需要对象引用,那么拥有成员指针有什么意义呢?

【问题讨论】:

  • 不能用函数指针来通过指针调用对象的特定方法。成员函数指针是必要的,因为它也涉及提供的对象指针。 (没有对象指针,就不能调用非静态方法,不能用成员函数指针,也不能用其他任何方式。)
  • 感谢@genpfault 的编辑。

标签: c++ opengl graphics


【解决方案1】:

拥有指向成员的指针的意义在于,您可以将它与任何对象一起使用,而不仅仅是预先确定的对象。

指向成员的指针更类似于数组索引而不是指针;如果您存储数字k,则可以检索任何数组的k:th 元素,只要您还知道从哪个数组中检索它即可。

如果您想在预定对象上调用函数,那么指向成员的指针不是您想要的——您可能需要std::functionstd::bind

一个非常简单的例子:

struct A
{
    A(const std::string& nm) : name(nm){}
    void f() { cout << name << " f\n";}
    void g() { cout << name << " g\n";}
    std::string name;
};

int main()
{
    A a("a");
    A b("b");
    using fun = std::function<void()>;
    std::vector<fun> fns = {std::bind(&A::f, a),
                            std::bind(&A::g, a),
                            std::bind(&A::f, b)};

    for (auto& f: fns)
        f();
}

【讨论】:

  • 我认为 std::function 是我正在寻找的,导致我想在 B 类内部调用 A 类的成员函数,而不向 B 类发送 A 类对象引用。这会很有帮助如果您可以举一个简单的用例示例。谢谢。
  • 自动类型会推断出什么?
  • @Tesla 向量元素的类型,和往常一样。即std::function&lt;void()&gt;
  • 好的,谢谢,我会在代码中试试这个并返回。
  • 是的,它正在工作,很好。现在我可以映射 而不是。谢谢先生。
猜你喜欢
  • 2018-09-12
  • 2012-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
相关资源
最近更新 更多