C++ 结构体和类型定义

7

我不确定标题的意思,因为我不知道它实际上是关于什么的。

我试图理解下面链接中的代码:

基于颜色的粒子滤波

我大致了解程序所做的事情,但我无法理解“state.h”。这段代码是做什么用的呢?特别是“typedef”、“State_”和“pp”这些部分对我来说看起来很奇怪。

为了更清晰地表达,请看以下代码片段:

struct StateData;
struct State_;
typedef State_ (*State)(StateData&);
struct State_
{
    State_( State pp ) : p( pp ) { }
    operator State()
    {
        return p;
    }
    State p;
};

State_ state_start(StateData& d);
State_ state_selecting(StateData& d);
State_ state_initializing(StateData& d);
State_ state_tracking(StateData& d);

任何形式的帮助都将不胜感激。
4个回答

5
简而言之:State是函数指针的别名。State_是一个包装类,具有State成员,并且可以隐式转换为该State
需要使用State_包装器的原因是没有办法表达返回相同类型函数指针的函数。该包装器消除了自引用。
逐行解释:
struct StateData;

一个类StateData的前置声明。
struct State_;

一个类 State_ 的前向声明。
typedef State_ (*State)(StateData&);

这段内容有些棘手。它将 State 定义为一个类型别名,可以指向一个返回 State_ 并以 StateData& 为参数的函数指针。代码片段末尾声明的函数可以由此类型的函数指针指向。
在我看来,考虑到已经有一个 State_ 类,所选择的名称非常令人困惑。虽然我通常反对匈牙利命名法,但我建议始终应用后缀或前缀来表示函数指针,例如 state_funstate_handlerstate_callback
struct State_
{

这是 State_ 类的定义。

    State_( State pp ) : p( pp ) { }

这定义了一个类的构造函数。参数是之前所定义的函数指针类型,它初始化将很快声明的成员。

    operator State()
    {
        return p;
    }

一个成员函数。更具体地说,是用户定义的转换为函数指针类型。
    State p;

声明在构造函数中初始化的成员。

};

State_ state_start(StateData& d);
State_ state_selecting(StateData& d);
State_ state_initializing(StateData& d);
State_ state_tracking(StateData& d);

自由函数,可以被一个State指向。


谢谢你的回答,但是我不理解"operator"函数。你可以再解释一下吗? @user2079303 - Anita W. Smith
@AnitaW.Smith,您不理解其中的哪一部分?您学习过用户定义转换吗? - eerorika
以前从未听说过。我会搜索一下。如果很容易解释的话,你能简要告诉我它是做什么的吗?@user2079303 - Anita W. Smith
@AnitaW.Smith 它允许你将 State_ 隐式转换为 State。像这样:State_ s(state_start); State fun_ptr = s; - eerorika
值得一提的是,这是编写返回自身地址的函数(或具有相同签名的函数)的唯一方法。如果没有结构体中间层,您将会得到无限递归。 - StoryTeller - Unslander Monica

3

State_ 是一个结构体类型。

State 是一个指向函数的指针,接受一个类型为 StateData& 的参数并返回 State_

typedef a b; 定义了一个类型 b,它与 a 完全相同。

p 是类 State_ 的一个字段,pp 是构造函数的一个参数。 p(pp) 是构造函数专用的特殊语法,将 p 初始化为 pp 的值。


1
这句话的意思是:“声明了一个名为StateData的结构体。”
struct StateData;

typedef关键字用于创建类型的新别名
例子:

typedef int mynumber; /// mynumber is an alias of type of int 
mynumber number = 3; /// so you can do this (number is a type of int just the int name is different)

其中的一个优点是,如果您有大量的mynumber实例,您可以轻松地更改数字变量的数据类型:
示例:

typedef int mynumber;
mynumber number1 = 3;  
mynumber number2 = 4;
mynumber number3 = 5; 
// what if you want to make all this type of double? or a float? easy
// just change the int to a double or float like this
    typedef float mynumber;
    typedef double mynumber;

这段话的意思是:“这个声明了一个名为State_的结构体”。
struct State_;

这个定义了之前声明的 State_。
struct State_
{
    State_( State pp ) : p( pp ) { }
    operator State()
    {
        return p;
    }
    State p;
};

这是一个列表初始化p的例子。它初始化了在结构体内声明的p(即State p)。
State_( State pp ) : p( pp )
{ 
}

这些原型函数返回一个接受 StateData 引用的 State_。
State_ state_start(StateData& d);
State_ state_selecting(StateData& d);
State_ state_initializing(StateData& d);
State_ state_tracking(StateData& d);

1

typedef在定义函数指针时非常有用。您有一个具有以下头文件的函数。State_是返回类型,输入是对StateData的引用。

State_ function (StateData&)

然后只需添加星号(并使用括号解决优先级)来描述指向此函数的指针。
State_ (*State) (StateData&)

然后在其前面加上typedef以将其定义为新类型。现在你有了一个新类型,可以在其他地方使用它。typedef用于创建类型别名,使你的代码更易读。
typedef State_ (*State) (StateData&)

现在这种状态类型可以在其他地方使用。使用这种新类型声明一个新变量p
State p

使用新的State类型作为构造函数的输入。
State_(State pp)

使用typedef指定函数指针类型可使编写接受其他函数作为输入的函数更加易读。


C++问题,如果是初学者,阅读C书籍是没有任何好处的。 - deW1
我已经从问题中删除了对书籍的引用。 - Jay Rajput

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接