【问题标题】:struct inside a class that has a pointer to a function requires forward declaration of functions outside of the class?具有指向函数的指针的类内的结构需要在类外前向声明函数?
【发布时间】:2019-11-06 05:54:11
【问题描述】:

我的类 Menu 中有一个私有结构,其中包含菜单项属性。这些属性之一是指向函数的指针。当我在类外转发声明函数时,似乎我所写的内容有效,但是在类外定义函数似乎是非常糟糕的做法。

#pragma once
#include <string>

//forward declaration outside the class
void completelyRandom();//does not throw error
class Menu
{

private:
    typedef void(*Menu_Processing_Function_Ptr)();

    struct MenuItem
    {
        unsigned int  number;
        const char *  text;
        Menu_Processing_Function_Ptr p_processing_function;
    };

    MenuItem menu[] =
    {
        {1, "Completely random", completelyRandom}

    };

public:
    Menu();

    ~Menu();
};

这是一些引发错误但更接近我希望的代码:

#pragma once
#include <string>


class Menu
{

private:
    typedef void(*Menu_Processing_Function_Ptr)();

    struct MenuItem
    {
        unsigned int  number;
        const char *  text;
        Menu_Processing_Function_Ptr p_processing_function;
    };

    MenuItem menu[1] =
    {
        {1, "Completely random", completelyRandom}

    };

public:
    Menu();
    //declaration within the class
void completelyRandom();//does throw error
    ~Menu();
};

我尝试在 Menu 范围内移动 completeRadom() 声明,但得到错误

a value of type "void (Menu::*)()" cannot be used to initialize an entity of type "Menu::Menu_Processing_Function_Ptr"

有没有一种方法可以转发声明符合最佳实践的函数?还是应该为自己糟糕的设计选择感到后悔并重新开始?

【问题讨论】:

  • 您显示的代码中的唯一错误是您无法定义没有大小的数组。您必须指定menu 数组的大小。这也是显示here 的唯一错误(如果您设置数组的大小,它会消失)。所以请创建一个合适的minimal reproducible example,我们可以自己复制和复制问题。
  • 如果您提供初始化列表,则不会。在这种情况下,大小为 1。
  • 不适用于类内内联初始化,因为类中不允许使用 incomplete types。另见this non-static data member reference
  • 您展示的第二个示例确实应该给出您所说的错误,这是因为指向非成员函数的指针不等于指向成员函数的指针。 (非静态)成员函数需要调用一个对象(在函数内部变成this),这是作为隐藏的第一个参数隐式传递的。非成员函数没有。
  • 我明白了。我没有想到要搜索“指向成员函数的指针”而不是“指向函数的指针”。快速检查似乎提供了一个解决方案——明天我要睡着了,我会试一试。将发布解决方案供其他人查看是否一切正常。感谢您的帮助!

标签: c++ pointers struct forward-declaration


【解决方案1】:

“非静态成员函数(实例方法)有一个隐式参数(this 指针),它是指向它正在操作的对象的指针,因此对象的类型必须作为对象类型的一部分包含在内函数指针。" - https://en.wikipedia.org/wiki/Function_pointer

查看此代码以获取示例:

#pragma once
#include <string>

class Menu
{

private:
    //By specifying the class type for the pointer -> 'Menu::' in this case 
    // we no longer have to forward declare the functions
    //outside of the class
    typedef void(Menu::*Menu_Processing_Function_Ptr)();

    struct MenuItem
    {
        unsigned int  number;
        const char *  text;
        Menu_Processing_Function_Ptr p_processing_function;
    };

    MenuItem menu[1] =
    {
        {1, "Completely random", completelyRandom}

    };

public:
    Menu();
void completelyRandom(); // no longer throws an error
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2023-03-22
    • 2011-10-11
    • 2021-01-29
    • 2012-12-26
    • 1970-01-01
    • 2011-06-20
    相关资源
    最近更新 更多