繁体   English   中英

如何在C ++中从实例化对象的函数指针调用函数?

[英]How to call a function from a function pointer of an instantiated object in C++?

我有两个类SimIElement IElement类定义函数指针,而Sim类则具有IElement指针向量。 什么是调用指向的自定义函数指针函数的正确方法IElement ,因为我有一个向量IElement*

换句话说,我有

std::vector<IElement*> nodes;

我需要从IElement调用指向函数:

nodes[i]->*SetInput(); // ERROR: Identifier "SetInput" is undefined

我以为我有这个错误,因为nodes是指针的向量,并且在调用其指向函数之前我不知道如何解引用nodes[i]

感谢您的任何建议。

下面是该代码的一些更详细的片段。

我有错误的IElement方法的Undefined identifierSim类的方法

#include <vector>
#include "Elements.h" // defines class IElement in namespace Elements
void Sim::CreateNodes(int N) // this method belongs to the Sim class in namespace "Simulations"
{
    nodes = std::vector<Elements::IElement*>(N);
    int i = 0;
    while (i < N)
    {
        nodes[i] = new Elements::IElement(true); // for the sake of the example
        nodes[i]->*SetInput(); // ERROR: Identifier "SetInput" is undefined
        i++;
    }
}

而在Elements命名空间中,我有IElement类声明

class IElement
{
public:
    typedef void(IElement::*SetInputFc_ptr)();
    IElement(bool); // normalizeInput
    ~IElement();
    SetInputFc_ptr SetInput;
};

和类IElement实现

IElement::IElement(bool normalizeInput)
{
    if (normalizeInput)
    {
        this->SetInput= &(this->SetInput_Sum);
    }
    else
    {
        this->SetInput= &(this->SetInput_Const);
    }
}

您都需要使用常规成员运算符从IElement对象获取SetInput成员值,然后使用->*IElement对象上调用成员函数。 假设您要对两个都使用相同的IElement

(nodes[i]->*(nodes[i]->SetInput))();

或将这两个语句重写为:

Elements::IElement* node = Elements::GetElement(i);
nodes[i] = node;
(node->*(node->SetInput))();

顺便说一句, &(this->SetInput_Sum)不是获得指向成员的指针的官方有效方法。 如果您的编译器接受它,则允许它作为扩展。 IElement构造函数应编写为:

IElement::IElement(bool normalizeInput)
{
    if (normalizeInput)
    {
        this->SetInput= &IElement::SetInput_Sum;
    }
    else
    {
        this->SetInput= &IElement::SetInput_Const;
    }
}

这似乎也像XY问题 C ++具有一些类,这些类意味着您可以首先通过子类化并拥有相同版本的标准化和非标准化版本来避免if出现。 相应地重写SetInput

大致播放如下:

class IElement
{
public:
    IElement();
    virtual ~IElement();

    virtual void SetInput();
};

class IElementNormalized : IElement {
    IElementNormalized();
    virtual ~IElementNormalized();

    virtual void SetInput();
};

面向对象的设计原则通常会引导您使用类为您完成很多工作,从而避免了让各个类进行区分的需求。

您可以始终捕获构造函数上使用的布尔值,并在执行所需的任何操作时将其作为属性引用,在需要知道的每个函数中按程序进行操作。

通过指针调用方法的简单示例。

#include <vector>

class IElement
{
    public:
        void action() {}
};

using MemberPtr = void (IElement::*)();    
MemberPtr Action = &IElement::action;

int main()
{
    std::vector<IElement*>  nodes{1, new IElement};

    (nodes[0]->*Action)();
    // Note the braces around the expression before the call.
    // This is because `()` binds tighter than `->*` so you need the
    // extra braces to force the `->*` to bind first so you can then call
    // the resulting method.

    //  nodes[0]->*Action();  // This will not compile.
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM