无法在C ++中初始化方法指针的映射 [英] can't initialize map of method pointers in c++

查看:109
本文介绍了无法在C ++中初始化方法指针的映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有如下功能:

//Parser.cpp
//...
Parser::Parser(CommandFactory & fact, 
               ArrayList<std::string> & expression)
{

    operations["*"] = &fact.createMultiplyCommand; //error C2276
    operations["/"] = &fact.createAdditionCommand; //error C2276
    operations["+"] = &fact.createAdditionCommand; //error C2276
    operations["%"] = &fact.createModulusCommand; //error C2276
    operations["-"] = &fact.createSubtractionCommand; //error C2276

    infixToPostfix(fact,expression);

}
//...

//Parser.h
//...

    Parser (CommandFactory & fact,
            ArrayList<std::string> & expression);

    Stack<Command*> tempCommandStack;
    ArrayList<Command*> postfix;

    /// Destructor.
    ~Parser (void);

private:
    //syntax is: <return_type> (*)()
    //syntax for a class method is: <return_type> (<class_name> *)();
    //syntax with a typedef is: typedef <return_type> (<class_name> * <typedef_name>)();
    //                          typedef <return_type> (*<typedef_name>)()


    std::map<std::string, Command * (*)()> operations; 
    std::map<std::string,int> precedence;
//...

了解CommandFactory是抽象类(传入的内容是具体的)也可能会有所帮助

It also may help to know that CommandFactory is an abstract class (what is passed in is concrete)

我收到的错误是C2276:'&' :对绑定成员函数表达式的非法操作.

The error I receive is C2276: '&' : illegal operation on bound member function expression.

当我定义映射时,我不知道我到底在做什么.有什么想法吗?

I don't know what I'm doing wrong exactly when I define the mapping. Any ideas?

//CommandFactory.h
#ifndef _COMMANDFACTORY_H_
#define _COMMANDFACTORY_H_

#include "Subtract.h"
#include "Add.h"
#include "Divide.h"
#include "Multiply.h"
#include "Modulus.h"
#include "Negation.h"
class CommandFactory
{
public:

    virtual Subtract * createSubtractionCommand() = 0;
    virtual Add * createAdditionCommand() = 0;
    virtual Divide * createDivisionCommand() = 0;
    virtual Multiply * createMultiplyCommand() = 0;
    virtual Modulus * createModulusCommand() = 0;
    virtual Negation * createNegationCommand() = 0;
    ~CommandFactory(void);

};

#endif   

//StackCommandFactory.h

#ifndef _STACKCOMMANDFACTORY_H_
#define _STACKCOMMANDFACTORY_H_

#include "Add.h"
#include "Subtract.h"
#include "Divide.h"
#include "Multiply.h"
#include "Modulus.h"
#include "CommandFactory.h"


class StackCommandFactory : public CommandFactory
{
public:



    virtual Subtract * createSubtractionCommand(void);
    virtual Add * createAdditionCommand(void);
    virtual Divide * createDivisionCommand(void);
    virtual Multiply * createMultiplyCommand(void);
    virtual Modulus * createModulusCommand(void);
    virtual Negation * createNegationCommand(void);

protected:
    Subtract * sub;
    Add * add;
    Divide * div;
    Multiply * mul;
    Modulus * mod;
    Negation * neg;

};

#endif   // !defined _STACKCOMMANDFACTORY_H_

//StackCommandFactory.cpp
#include "StackCommandFactory.h"

Subtract * StackCommandFactory::createSubtractionCommand(void)
{
    return sub;
}

Add * StackCommandFactory::createAdditionCommand(void)
{
    return add;
}

Divide * StackCommandFactory::createDivisionCommand(void)
{
    return div;
}

Multiply * StackCommandFactory::createMultiplyCommand(void)
{
    return mul;
}

Modulus * StackCommandFactory::createModulusCommand(void)
{
    return mod;
}

Negation * StackCommandFactory::createNegationCommand(void)
{
    return neg;
}

推荐答案

您的代码存在一些问题.主要集中在成员函数而不是全局函数的使用上.您尝试从对象获取成员函数,而应该从类本身获取成员函数. (即,您需要&CommandFactory::createAdditionCommand而不是&fact.createAdditionCommand.)但这会导致成员函数未绑定,这意味着您需要使用(fact.*fn)()进行调用-即,使用CommandFactory类的对象.这不是理想的选择,也不是您想要的.您正在寻找绑定成员函数.可以在非C ++-11应用程序中使用它们,但是很难. 您可以使用boost库来真正地解决此问题(除了将某些std转换为boost样式之外,下面的代码几乎可以保持不变.)如果您使用的是C ++-11,则可以使用C ++ -11个功能对象.

There's a few issues with your code. Mostly centring about the use of member functions rather than global functions. You try to get the member functions from an object, where you should be getting them from the class itself. ( i.e. instead of &fact.createAdditionCommand you need &CommandFactory::createAdditionCommand.) But this results in an unbound member function, which means you need to call it using (fact.*fn)() - i.e. with an object of the CommandFactory class. This is not ideal - and not what you're looking for. You are looking for a bound member function. Using these in non C++-11 applications is possible, but ugly. You can use boost libraries to really help with that (and the code below will pretty much work unchanged other than some std to boost style changes.) If you're using C++-11 then you can use the C++-11 function objects.

这是从您的来源得到的完整示例:

Here's a complete example derived from your source:

#include <vector>
#include <map>
#include <functional>
#include <string>

struct Command {};
struct Subtract : Command {};
struct Add : Command {};

class CommandFactory
{
  public:

    virtual Subtract * createSubtractionCommand() = 0;
    virtual Add * createAdditionCommand() = 0;
};

class StackCommandFactory : public CommandFactory
{
  public:

    virtual Subtract * createSubtractionCommand(void);
    virtual Add * createAdditionCommand(void);

    Subtract * sub;
    Add * add;
};

Subtract * StackCommandFactory::createSubtractionCommand(void) { return sub; }
Add * StackCommandFactory::createAdditionCommand(void) { return add; }

class Parser
{
  public:
    Parser (CommandFactory & fact);

    std::map<std::string, std::function<Command*()> > operations; 
};

Parser::Parser(CommandFactory & fact)
{
  operations["+"] = std::bind(&CommandFactory::createAdditionCommand, &fact);
  operations["-"] = std::bind(&CommandFactory::createSubtractionCommand, &fact);
}

#include <iostream>
int main()
{
  Add add;
  Subtract sub;

  StackCommandFactory command_factory;
  command_factory.add = &add;
  command_factory.sub= &sub;
  Parser parser(command_factory);

  std::cout<<"&add = "<<&add<<std::endl;
  std::cout<<"Add = " <<  parser.operations["+"]() <<std::endl;
  std::cout<<"&sub = "<<&sub<<std::endl;
  std::cout<<"Sub = " <<  parser.operations["-"]() <<std::endl;

  return 0;
}

我得到了输出

&add = 0x7fff58d538d8
Add = 0x7fff58d538d8
&sub = 0x7fff58d538d0
Sub = 0x7fff58d538d0

表明通过解析器返回的Add对象与存储在CommandFactory中的对象相同. (与减法对象相同)

Showing that the Add object returned by going through the parser is the same as that stored into the CommandFactory. (And same for the Subtract object)

这篇关于无法在C ++中初始化方法指针的映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆