如何理解本声明中的类型
How to understand the typedef in this declaration
最近,我读了这本书有效的C ,并且在项目35中有关于Typedef的声明使我感到困惑。
class GameCharacter; // Question1: Why use forward declaration?
int defaultHealthCalc(const GameCharacter& gc);
class GameCharacter{
public:
typedef int (*HealthCalcFunc)(const GameCharacter&); // Question 2: What does this mean?
explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)
: healthFunc(hcf)
{}
int healthValue() const
{return healthFunc(*this); }
private:
HealthCalcFunc healthFunc;
};
所以我的第一个问题是:为什么作者在这里使用前向声明?有什么具体原因吗?
我的第二个问题是:我如何理解Typedef声明,以及如何使用它?我只知道typedef int MyInt;
所以我的第一个问题是,为什么作者在这里使用远期声明?
由于函数的声明defaultHealthCalc
使用const GameCharacter&
作为参数的类型,因此需要预先声明GameCharacter
。
我的第二个问题是如何理解Typedef声明
它声明了类型名称HealthCalcFunc
,这是一种用于功能的指针,它将const GameCharacter&
作为参数并返回int
。
以及如何使用它?
正如代码样本所示,
explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc) // declare a parameter with type HealthCalcFunc;
// the default argument is function pointer to defaultHealthCalc
: healthFunc(hcf) // initialize healthFunc with hcf
{}
int healthValue() const
{return healthFunc(*this); } // invoke the function pointed by healthFunc
HealthCalcFunc healthFunc; // declare a member with type HealthCalcFunc
由于使用 GameCharacter
的 defaultHealthCalc
的正向声明,因此需要向前声明。如果没有远期声明,编译器将不知道以后会有一种名为 GameCharacter
的类型,因此您需要转发声明,或在函数声明之前移动定义。
typedef
的意思是命名int(*)(const GameCharacter&)
HealthCalcFunc
类型。这是int(const GameCharacter&)
的功能指针。因此,Typedefs非常不可读,建议使用using
声明:
using HealthCalcFunc = int(*)(const GameCharacter&);
所以我的第一个问题是,作者为什么在这里使用远期声明?
以便编译器知道遇到int defaultHealthCalc(const GameCharacter& gc);
行时GameCharacter
是一个有效名称。
我的第二个问题是如何了解Typedef声明以及如何使用它?
理想情况下,您做不再使用它。
从C 11开始,using
是一种优越的选择,因为它更可读。与typedef
'ED功能指针不同,它显然将名称与名称所描述的名称分开。比较以下内容:
typedef int (*HealthCalcFunc)(const GameCharacter&);
与此:
using HealthCalcFunc = int (*)(const GameCharacter&);
在typedef
版本中,名称HealthCalcFunc
在两侧都被名称所描述的围绕。这损害了可读性。
但仍然可以改进代码,因为C 11还引入了std::function
作为函数指针上方的抽象层的替代方案。
using HealthCalcFunc = std::function<int(const GameCharacter&)>;
这是如此可读性,几乎不必解释。HealthCalcFunc
是返回int
并采用const GameCharacter&
的函数。
defaultHealthCalc
功能符合此定义。这是一个完整的例子:
#include <functional>
class GameCharacter;
int defaultHealthCalc(const GameCharacter& gc);
class GameCharacter {
public:
using HealthCalcFunc = std::function<int(const GameCharacter&)>;
explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)
: healthFunc(hcf)
{}
int healthValue() const
{return healthFunc(*this); }
private:
HealthCalcFunc healthFunc;
};
关于std::function
的伟大之处是您不仅限于独立的功能。您可以通过所有类似功能的东西。以下是一些示例:
struct Functor
{
int f(const GameCharacter& gc);
};
int main()
{
// normal function:
GameCharacter character1(defaultHealthCalc);
// lambda:
GameCharacter character2([](auto const& gc) { return 123; });
// using std::bind:
Functor functor;
using namespace std::placeholders;
GameCharacter character3(std::bind(&Functor::f, functor, _1));
}
另请参见我应该使用std ::函数或C 中的功能指针。
typedef int (*HealthCalcFunc)(const GameCharacter&);
在功能指针类型中声明名为HealthCalcFunc
的typedef
,其中功能签名返回int
并采用const GameCharacter&
的参数。
需要向前声明,因为该类用作typedef
中的参数类型。
不需要严格需要GameCharacter
的正向声明;该功能声明可以读取:
int defaultHealthCalc(const class GameCharacter& gc);
具有与原始代码相同的效果。但是,将远期声明放在自己的行中被认为更可读。
- 将类型声明为类型模板参数的模板参数的一部分是否合法?
- 当返回类型声明为 ListNode 时,我们是否可以返回 false<T>*
- 如何使用自定义类型声明Arduino数组?
- 将函数参数类型声明为 auto
- 使用typedef'ed返回类型声明友元函数时出现编译器错误
- 在没有标识符的情况下如何读取复杂的C++类型声明?
- 模板函数参数显式类型声明
- 使用指针遍历一系列基元类型声明?
- 字符类型声明和验证
- 使用本地类型声明的G lambda被使用但从未定义 - 确实是一个错误
- 为什么 c++ lambda 捕获不需要类型声明?
- 为什么没有"int"类型声明时输出不同?
- C++如何使用虚拟基类型声明全局静态分配的变量
- 我可以使用预处理器将一个类型声明替换为另一个类型声明吗?
- 如何将数据类型声明从.cpp文件传输到 .cu 文件
- C++17 枚举类型声明
- 条件类型声明
- 具有特定参数的特定构造函数的类型声明
- 我可以使用相同的名称为周围作用域中的类型声明成员类型别名吗
- 函数调用之前,C 类型声明