c++ - 如何在静态成员函数中使用指向成员函数的指针

问题描述

我实际上试图在静态函数中使用指针,该函数与我试图在指针中使用的函数在同一个类中。 我实际上被要求像这样使用这个类:

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);
};
,

谢谢大家的回答 我现在对这个主题和我的项目工作有了更好的了解。