如何理解这个声明中的typedef
How to understand the typedef in this declaration
最近看了Effective 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;
typedef int (*HealthCalcFunc)(const GameCharacter&);
为函数指针类型声明一个名为HealthCalcFunc
的typedef
,其中函数签名returns 为int
并采用const GameCharacter&
的参数。
需要前向声明,因为 class 在 typedef
中用作参数类型。
前向声明是因为defaultHealthCalc
的前向声明,它使用了GameCharacter
。如果没有前向声明,编译器就不知道后面会有一个名为GameCharacter
的类型,所以你需要前向声明它,或者把定义移到函数声明之前。
即typedef
的意思是命名类型int(*)(const GameCharacter&)
HealthCalcFunc
。那是一个指向 int(const GameCharacter&)
的函数指针。因此,typedef 很难读,建议改用 using
声明:
using HealthCalcFunc = int(*)(const GameCharacter&);
So my first question is that why the author use forward declaration here?
因为函数defaultHealthCalc
的声明使用了const GameCharacter&
作为参数的类型,所以需要提前声明GameCharacter
And my second question is how to understand the typedef declaration
它声明了一个类型名HealthCalcFunc
,它是一种指向函数的指针类型,它以const GameCharacter&
为参数,returns int
.
and how to use it?
正如代码示例所示,
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
So my first question is that why the author use forward declaration here?
以便编译器在遇到 int defaultHealthCalc(const GameCharacter& gc);
行时知道 GameCharacter
是一个有效名称。
And my second question is how to understand the typedef declaration and how to use it?
理想情况下,您不再使用它。
从 C++11 开始,using
是更好的选择,因为它更具可读性;与 typedef
编辑的函数指针不同,它清楚地将名称与名称描述的内容分开。比较一下:
typedef int (*HealthCalcFunc)(const GameCharacter&);
有了这个:
using HealthCalcFunc = int (*)(const GameCharacter&);
在 typedef
版本中,名称 HealthCalcFunc
两边都被名称描述的内容包围。这会影响可读性。
但是代码仍然可以改进,因为 C++11 还引入了 std::function
作为 and/or 函数指针之上的抽象层的替代。
using HealthCalcFunc = std::function<int(const GameCharacter&)>;
这是非常可读的,几乎不需要解释。 HealthCalcFunc
是一个 returns 一个 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));
}
另见 Should I use std::function or a function pointer in C++?。
GameCharacter
的前向声明不是严格需要的;函数声明可以是:
int defaultHealthCalc(const class GameCharacter& gc);
与原代码效果相同。但是将前向声明单独放在一行被认为更具可读性。
最近看了Effective 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;
typedef int (*HealthCalcFunc)(const GameCharacter&);
为函数指针类型声明一个名为HealthCalcFunc
的typedef
,其中函数签名returns 为int
并采用const GameCharacter&
的参数。
需要前向声明,因为 class 在 typedef
中用作参数类型。
前向声明是因为defaultHealthCalc
的前向声明,它使用了GameCharacter
。如果没有前向声明,编译器就不知道后面会有一个名为GameCharacter
的类型,所以你需要前向声明它,或者把定义移到函数声明之前。
即typedef
的意思是命名类型int(*)(const GameCharacter&)
HealthCalcFunc
。那是一个指向 int(const GameCharacter&)
的函数指针。因此,typedef 很难读,建议改用 using
声明:
using HealthCalcFunc = int(*)(const GameCharacter&);
So my first question is that why the author use forward declaration here?
因为函数defaultHealthCalc
的声明使用了const GameCharacter&
作为参数的类型,所以需要提前声明GameCharacter
And my second question is how to understand the typedef declaration
它声明了一个类型名HealthCalcFunc
,它是一种指向函数的指针类型,它以const GameCharacter&
为参数,returns int
.
and how to use it?
正如代码示例所示,
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
So my first question is that why the author use forward declaration here?
以便编译器在遇到 int defaultHealthCalc(const GameCharacter& gc);
行时知道 GameCharacter
是一个有效名称。
And my second question is how to understand the typedef declaration and how to use it?
理想情况下,您不再使用它。
从 C++11 开始,using
是更好的选择,因为它更具可读性;与 typedef
编辑的函数指针不同,它清楚地将名称与名称描述的内容分开。比较一下:
typedef int (*HealthCalcFunc)(const GameCharacter&);
有了这个:
using HealthCalcFunc = int (*)(const GameCharacter&);
在 typedef
版本中,名称 HealthCalcFunc
两边都被名称描述的内容包围。这会影响可读性。
但是代码仍然可以改进,因为 C++11 还引入了 std::function
作为 and/or 函数指针之上的抽象层的替代。
using HealthCalcFunc = std::function<int(const GameCharacter&)>;
这是非常可读的,几乎不需要解释。 HealthCalcFunc
是一个 returns 一个 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));
}
另见 Should I use std::function or a function pointer in C++?。
GameCharacter
的前向声明不是严格需要的;函数声明可以是:
int defaultHealthCalc(const class GameCharacter& gc);
与原代码效果相同。但是将前向声明单独放在一行被认为更具可读性。