如何从 C++ 中实例化对象的函数指针调用函数?
How to call a function from a function pointer of an instantiated object in C++?
我有两个 class,Sim
和 IElement
。 class IElement
定义了一个函数指针,而 class Sim
有一个 IElement
指针向量。鉴于我有一个 IElement*
的向量,从 IElement
中定义的函数指针调用指向函数的正确方法是什么?
换句话说,我有
std::vector<IElement*> nodes;
我需要从 IElement
:
调用一个指向函数
nodes[i]->*SetInput(); // ERROR: Identifier "SetInput" is undefined
我假设我有这个错误,因为 nodes
是一个指针向量,我不知道如何在调用它的指向函数之前取消引用 nodes[i]
。
感谢您的任何建议。
下面给出了更详细的代码片段。
Sim
class 的方法 IElement
的方法出现错误 Undefined identifier
#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
命名空间中,我有 class IElement
声明
class IElement
{
public:
typedef void(IElement::*SetInputFc_ptr)();
IElement(bool); // normalizeInput
~IElement();
SetInputFc_ptr SetInput;
};
和 class 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 Problem。 C++ 具有 类,这意味着您可以首先通过子类化并具有相同的规范化和 non-normalized 版本来避免 if
。相应地覆盖 SetInput
。
结果大致是这样的:
class IElement
{
public:
IElement();
virtual ~IElement();
virtual void SetInput();
};
class IElementNormalized : IElement {
IElementNormalized();
virtual ~IElementNormalized();
virtual void SetInput();
};
Object-Oriented 设计原则通常倾向于使用 类 为您完成大量工作,避免需要个人 类 像这样进行区分。
您始终可以捕获构造函数上使用的布尔值,并在执行您需要的任何操作时将其作为 属性 引用,在每个需要知道的函数中按程序执行。
通过指针调用方法的简单例子
#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.
}
我有两个 class,Sim
和 IElement
。 class IElement
定义了一个函数指针,而 class Sim
有一个 IElement
指针向量。鉴于我有一个 IElement*
的向量,从 IElement
中定义的函数指针调用指向函数的正确方法是什么?
换句话说,我有
std::vector<IElement*> nodes;
我需要从 IElement
:
nodes[i]->*SetInput(); // ERROR: Identifier "SetInput" is undefined
我假设我有这个错误,因为 nodes
是一个指针向量,我不知道如何在调用它的指向函数之前取消引用 nodes[i]
。
感谢您的任何建议。
下面给出了更详细的代码片段。
Sim
class 的方法 IElement
Undefined identifier
#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
命名空间中,我有 class IElement
声明
class IElement
{
public:
typedef void(IElement::*SetInputFc_ptr)();
IElement(bool); // normalizeInput
~IElement();
SetInputFc_ptr SetInput;
};
和 class 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 Problem。 C++ 具有 类,这意味着您可以首先通过子类化并具有相同的规范化和 non-normalized 版本来避免 if
。相应地覆盖 SetInput
。
结果大致是这样的:
class IElement
{
public:
IElement();
virtual ~IElement();
virtual void SetInput();
};
class IElementNormalized : IElement {
IElementNormalized();
virtual ~IElementNormalized();
virtual void SetInput();
};
Object-Oriented 设计原则通常倾向于使用 类 为您完成大量工作,避免需要个人 类 像这样进行区分。
您始终可以捕获构造函数上使用的布尔值,并在执行您需要的任何操作时将其作为 属性 引用,在每个需要知道的函数中按程序执行。
通过指针调用方法的简单例子
#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.
}