简体   繁体   中英

how to use a pointer to member function inside a static member function in c++

I'm actually trying to use a pointer inside a static function which is in the same class as the functions that i'm trying to use inside the pointer. I'm actually asked to use the class like this :

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

This is how I would do if this function wasn't static :

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 is just an enum

You need to know where is the object whose member function should be invoked.

It doesn't matter how you know it, the point is that you have to know it, in some form or fashion. Perhaps a pointer to the object gets passed as an additional parameter:

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

Or, perhaps, a reference to the object gets passed in, instead of a pointer (resulting in a slight adjustment to the code), or maybe the object is somewhere else entirely. Maybe createOperand() calls some other function that returns a pointer or a reference to the instance of its class, but the point is that a member function cannot be invoked by itself. An object is required whose member function gets invoked. That's what a member function is, and how it differs from an ordinary function.

PS It doesn't matter whether all of this is "inside a static member function", or not. This is not a factor. The only factor is that inside a non-static member you always have this as an object that's available to you. But there is no law that requires you to invoke this 's member, via a pointer. If you have some other instance of the same class, somewhere, you can invoke its member function, instead of this one's.

No matter where you use the member function pointer to call a method, you need an object to do so. In your "This is how I would do if this function wasn't static" version you call the method on the current object this . In the static method, you need a different object of type Factory , because there is no this in the static method. I suspect that actually all methods of Factory should be static , though not touching that, you can do this:

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::createInt16,
                &Factory::createInt32,
                &Factory::createFloat,
                &Factory::createDouble,
                &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);
};

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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