16

好吧,我主要有:

void somefunction();
int main()
{
    //bla bla bla
    SomeClass myclass = SomeClass();
    void(*pointerfunc)() = somefunction;
    myclass.addThingy(pointerfunc);

    //then later i do
    myclass.actionWithDiffrentOutcomes();
}

void somefunction()
{
    //some code
}

在课堂上:

class SomeClass()
{
    public:
        void addThingy(void (*function)());
        void actionWithDiffrentOutcomes();
    private:
        std::vector<void (**)()> vectoroffunctions;
}
SomeClass::addThingy(void (*function)())
{
    vectoroffunctions.push_back(&function);
}
SomeClass::actionWithDiffrentOutcomes()
{
    (*vectoroffunctions[0])();;
}

我对指针有点新意,但我阅读了我的 c++ 书籍,谷歌搜索,分机。这似乎是正确的,可以编译,运行,但是当我调用“actionWithDiffrentOutcomes()”时,我遇到了访问冲突。我不知道该怎么办。这似乎是正确的,但显然有些地方是错误的。那么,当定义在另一个类中时,如何从一个类中调用一个函数呢?

我这样做是因为我无法将每个选项硬编码到 switch 语句中。

4

3 回答 3

20

您的代码几乎是正确的。您的向量错误地持有指向函数的指针,而不仅仅是指向函数的指针。addThingy正在将指针的地址添加function到 中vector,但该指针在下一行超出范围。

更改您的代码如下:

//Store pointers to functions, rather than
//pointers to pointers to functions
std::vector<void (*)()> vectoroffunctions;

SomeClass::addThingy(void (*function)())
{
    //Don't take the address of the address:
    vectoroffunctions.push_back(function);
}

此外,其余代码中有很多语法错误,这应该会阻止代码甚至编译。

于 2013-02-28T05:59:34.673 回答
12

问题在这里:

vectoroffunctions.push_back(&function);

您正在添加局部变量的地址。一旦你从函数返回,局部变量就会被销毁。向量存储的地址指向一个被破坏的对象,这就是你在运行时出现“访问冲突”错误的原因。

要解决此问题,请执行以下操作:

先改这个

std::vector<void (**)()> vectoroffunctions;

对此:

std::vector<void (*)()> _functions; //vector of function-pointer-type
                                    //I changed the name also!

这实际上与:

std::vector<void()> _functions; //vector of function-type

现在这样做:

_functions.push_back(function); //add copy! 

为了使其更灵活,您可以将模板与std::functionas 一起使用:

class A
{
    public:
        template<typename Function>
        void add(Function && fn) 
        {  
            _functions.push_back(std::forward<Function>(fn)); 
        }
        void invoke_all()
        {
           for(auto && fn : _functions)
                fn();
        }
    private:
        std::vector<std::function<void()>> _functions;
};

现在您可以使用它来存储函数和函子:

void myfunction() { std::cout << "myfunction" << std::endl ; }

struct myfunctor
{
       void operator()() { std::cout << "myfunctor" << std::endl ; }
};

A a;
a.add(myfunction);   //add function
a.add(myfunctor());  //add functor!
a.invoke_all();

输出(在线演示):

myfunction
myfunctor

希望有帮助。

于 2013-02-28T06:00:20.460 回答
1

函数指针更易读typedefs

typedef void (*RequiredFunction)();

然后你可以addThingy()这样声明:

    void addThingy(RequiredFunction function);

vectoroffunctions就像这样:

    std::vector<RequiredFunction> vectoroffunctions;

will的定义addThingy是:

void SomeClass::addThingy(RequiredFunction function)
{
    vectoroffunctions.push_back(function);
}

main()会看起来更像:

int main()
{
    SomeClass sc;
    RequiredFunction pointerfunc = somefunction;
    sc.addThingy(pointerfunc);
    sc.actionWithDiffrentOutcomes();
}

犯错的*s和s要少得多!&

于 2013-02-28T06:05:00.793 回答