C ++成员函数指针用例?

时间:2018-09-20 08:52:21

标签: c++ opengl graphics

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

  • GameObject(组件体系结构):

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

    • 处理所有着色器数据,并将其作为组件附加到GameObject。
    • 包含私有:void RegisterComponent(RCUpdateCallback&funcPtr);
  • MeshRenderer:

    • 处理分配的网格数据(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类调用方法时,我还需要Mesh对象的引用才能调用相应的函数指针。

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

现在我在存储回调中看不到任何意义,如果要发送对象引用,则可以通过引用调用所有方法。

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

1 个答案:

答案 0 :(得分: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();
}