簡體   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