gpt4 book ai didi

c++ - 在 C++ 中传递派生类时无法初始化仿函数对象

转载 作者:太空狗 更新时间:2023-10-29 23:20:42 25 4
gpt4 key购买 nike

这个问题源于我之前问过的一个问题here .我不能使用任何外部库或 C++ 11 规范。这意味着我不能使用 std::bind、std::function、boost::bind、boost::function 等。我必须自己编写。问题如下:

考虑代码:

编辑

这是一个完整的程序,它按要求展示了问题:

#include <map>
#include <iostream>


class Command {
public:
virtual void executeCommand() = 0;
};

class Functor {
public:
virtual Command * operator()()=0;
};

template <class T> class Function : public Functor {
private:
Command * (T::*fptr);
T* obj;
public:
Function(T* obj, Command * (T::*fptr)()):obj(obj),
fptr(fptr) {}

virtual Command * operator()(){
(*obj.*fptr)();
}
};

class Addition:public Command {
public:
virtual void executeCommand(){
int x;
int y;
x + y;
}
};

class CommandFactory {
public:
virtual Addition * createAdditionCommand() = 0;
};

class StackCommandFactory: public CommandFactory {
private:
Addition * add;
public:
StackCommandFactory():add(new Addition()) {}

virtual Addition * createAdditionCommand(){
return add;
}
};

void Foo(CommandFactory & fact) {
Function<CommandFactory> bar(&fact,&CommandFactory::createAdditionCommand);
}

int main() {
StackCommandFactory fact;
Foo(fact);
return 0;
}

它给出的错误是"no instance of constructor "Function<T>::Function [with T=CommandFactory] matches the argument list, argument types are: (CommandFactory *, Addition * (CommandFactory::*)())

我认为它在提示,因为我将派生类型传递给它。我必须使用抽象类的指针/引用,因为 fact以后可能不是 StackCommandFactory。

我不能说:

void Foo(CommandFactory & fact){
Function<CommandFactory> spf(&fact,&fact.createAdditionCommand); //error C2276

}

因为那时我收到错误 C2276,它说(如我链接到的问题)'&' : illegal operation on bound member function expression.

明确地说,我的问题是:“我如何初始化这个仿函数对象,以便我可以将它与上述接口(interface)一起使用?”

最佳答案

这是对我的原始答案的修改,它似乎可以满足您的需求,而无需使用 C++11 或 boost 中的任何仿函数。

#include <vector>
#include <map>
#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 CommandGetterImpl
{
public:
virtual CommandGetterImpl* clone() const=0;
virtual Command* get()=0;
virtual ~CommandGetterImpl() {};
};

class CommandGetter
{
public:
Command* get() { return impl_->get(); }
~CommandGetter() { delete impl_; }
CommandGetter( const CommandGetter & other ) : impl_(other.impl_?other.impl_->clone():NULL) {}
CommandGetter& operator=( const CommandGetter & other ) {
if (&other!=this) impl_= other.impl_?other.impl_->clone():NULL;
return *this;
}
CommandGetter() : impl_(NULL) {}
CommandGetter( CommandGetterImpl * impl ) : impl_(impl) {}
CommandGetterImpl * impl_;
};

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

std::map<std::string, CommandGetter > operations;
};

template<typename MEMFN, typename OBJ >
class MemFnCommandGetterImpl : public CommandGetterImpl
{
public:
MemFnCommandGetterImpl(MEMFN memfn, OBJ *obj) : memfn_(memfn), obj_(obj) {}
MemFnCommandGetterImpl* clone() const { return new MemFnCommandGetterImpl( memfn_, obj_) ; }
Command* get() { return (obj_->*memfn_)(); }
MEMFN memfn_;
OBJ * obj_;
};


template< typename MEMFN, typename OBJ >
CommandGetter my_bind( MEMFN memfn, OBJ * obj )
{
return CommandGetter( new MemFnCommandGetterImpl<MEMFN,OBJ>(memfn,obj) );
};

Parser::Parser(CommandFactory & fact)
{
operations["+"] = my_bind(&CommandFactory::createAdditionCommand, &fact);
operations["-"] = my_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["+"].get() <<std::endl;
std::cout<<"&sub = "<<&sub<<std::endl;
std::cout<<"Sub = " << parser.operations["-"].get() <<std::endl;

return 0;
}

关于c++ - 在 C++ 中传递派生类时无法初始化仿函数对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15733390/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com