簡體   English   中英

C ++從類內部的函數指針向量調用函數,該函數定義位於main中

[英]C++ calling a function from a vector of function pointers inside a class where the function definition is in main

好吧,我的主要任務是:

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 ++書籍,googled,ext。 並且這似乎是正確的,可以編譯,運行,但是當我調用“ actionWithDiffrentOutcomes()”時,出現訪問沖突。 我不確定該怎么辦。 這似乎是正確的,但顯然是錯誤的。 那么,當定義在另一個類中時,如何從一個類中調用函數呢?

我這樣做是因為我無法將每個選項硬編碼到switch語句中。

您的代碼幾乎是正確的。 您的向量錯誤地持有指向函數的指針,而不是簡單地指向函數的指針。 addThingyfunction指針的地址添加到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);
}

另外,在其余的代碼中,您還會遇到很多語法錯誤,這將使代碼甚至無法編譯。

問題在這里:

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::function一起使用:

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

希望能有所幫助。

使用typedefs函數指針更加清晰:

typedef void (*RequiredFunction)();

然后,您可以像這樣聲明addThingy()

    void addThingy(RequiredFunction function);

vectoroffunctions像這樣:

    std::vector<RequiredFunction> vectoroffunctions;

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少得多!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM