问题描述
我实际上试图在静态函数中使用指针,该函数与我试图在指针中使用的函数在同一个类中。 我实际上被要求像这样使用这个类:
class Factory {
public:
Factory() = default;
~Factory() = default;
static IOperand* createOperand(eOperandType type,const std::string& value);
private:
IOperand* createInt8(const std::string& value);
IOperand* createInt16(const std::string& value);
IOperand* createInt32(const std::string& value);
IOperand* createFloat(const std::string& value);
IOperand* createDouble(const std::string& value);
IOperand* createBigDecimal(const std::string& value);
};
如果这个函数不是静态的,我会这样做:
IOperand* Factory::createOperand(eOperandType type,const std::string& value)
{
IOperand* (Factory::*ptr[6])(const std::string&) = {
&Factory::createInt8,&Factory::createInt16,&Factory::createInt32,&Factory::createFloat,&Factory::createDouble,&Factory::createBigDecimal
};
return (*this.*ptr[type])(value);
}
ps: eOperandType 只是一个枚举
解决方法
您需要知道应该调用其成员函数的对象在哪里。
你如何知道它并不重要,关键是你必须以某种形式或方式知道它。也许指向对象的指针作为附加参数传递:
IOperand* Factory::createOperand(Factory *obj,eOperandType type,const std::string& value)
{
IOperand* (Factory::*ptr[6])(const std::string&) = {
&Factory::createInt8,&Factory::createInt16,&Factory::createInt32,&Factory::createFloat,&Factory::createDouble,&Factory::createBigDecimal
};
return ((*obj).*ptr[type])(value);
}
或者,可能传入的是对对象的引用,而不是指针(导致对代码的轻微调整),或者对象可能完全在其他地方。也许 createOperand()
调用其他一些函数,该函数返回指向其类实例的指针或引用,但关键是成员函数不能被自身调用。需要一个对象,其成员函数被调用。这就是成员函数,以及它与普通函数的区别。
附言所有这些是否都在“静态成员函数内部”并不重要。这不是一个因素。唯一的因素是,在非静态成员中,您始终可以使用 this
作为对象。但是没有法律要求您通过指针调用 this
的成员。如果你有同一个类的其他实例,你可以在某处调用它的成员函数,而不是 this
的。
无论在哪里使用成员函数指针调用方法,都需要一个对象来实现。在您的“如果此函数不是静态的,我会怎么做”版本中,您调用当前对象 this
上的方法。在静态方法中,您需要一个类型为 Factory
的不同对象,因为静态方法中没有 this
。我怀疑实际上 Factory
的所有方法都应该是 static
,虽然没有触及它,但你可以这样做:
struct IOperand {};
class Factory {
public:
Factory() = default;
~Factory() = default;
static IOperand* createOperand(size_t type,const std::string& value) {
Factory f;
IOperand* (Factory::*ptr[6])(const std::string&) = {
&Factory::createInt8,&Factory::createBigDecimal
};
return (f.*ptr[type])(value);
}
private:
IOperand* createInt8(const std::string& value);
IOperand* createInt16(const std::string& value);
IOperand* createInt32(const std::string& value);
IOperand* createFloat(const std::string& value);
IOperand* createDouble(const std::string& value);
IOperand* createBigDecimal(const std::string& value);
};
,
谢谢大家的回答 我现在对这个主题和我的项目工作有了更好的了解。