繁体   English   中英

为什么只有函数指针而不是函数变量?

[英]Why is there only pointer to function instead of var of function?

在C/C++中,我们可以声明/定义一个类型的函数指针,然后声明/定义一些这个类型的变量。 但我认为这是模棱两可的。

例如:

typedef void ( *pFunc )();
// typedef void ( aFunc )();
void theFunc() {
   cout << "theFunc has been called successfully." << endl;
};

int main() {
   pFunc pf0 = theFunc;
   pFunc pf1 = &theFunc;

   pf0();
   ( *pf0 )();
   pf1();
   ( *pf1 )();
};

理论上,只有pFunc pf1 = &theFunc; (*pf1)(); 是合法的,但以上都可以通过编译。

Pascal语法中,我们需要分别定义函数的vars或函数指针的vars,它们的含义是不同的,而且更加清晰(至少我是这么认为的)!

此外,我们不能声明/定义函数的变量而不是函数指针的变量! 我尝试了以下并失败了。

typedef void ( aFunc )();
aFunc af0 = theFunc;

如果使用其他类型,例如 int/double,则有非常严格的语法限制我们正确使用它们。 (如果int*int ,为什么*pf0pf0相同?!)

那么,我可以认为这是 C/C++ 标准的错误吗?

一些声明的类型:

// decltype of theFunc is void ()
// decltype of &theFunc is void (*) ()
// decltype of *theFunc is void (&) ()

现在,关于您的代码,由于函数可以隐式转换为指向该函数的指针,我们有:

using pFunc = void(*)();
using rFunc = void(&)();

pFunc p_fct = &theFunc; // no conversion
pFunc p_fct = theFunc;  // conversion lvalue to pointer
pFunc p_fct = *theFunc; // conversion lvalue reference to pointer

rFunc r_fct = *theFunc; // no conversion
rFunc r_fct = theFunc;  // conversion lvalue to lvalue reference
rFunc r_fct = &theFunc; // ERROR: conversion pointer to lvalue reference not allowed

到目前为止的转换。 现在,任何pFuncrFunc类型的对象都是可调用对象。 另外,请注意(*p_fct)(*r_fct)都是rFunc类型。 因此,您可以按照问题中的描述调用您的函数:

p_fct();    // callable object of type pFunc
r_fct();    // callable object of type rFunc
(*p_fct)(); // callable object of type rFunc
(*r_fct)(); // callable object of type rFunc

请注意,以下内容等效于上述内容:

using Func = void ();
Func* p_fct = &theFunc; // no conversion
Func& r_fct = *theFunc; // no conversion
p_fct();                // callable of type Func* or pFunc
r_fct();                // callablel of type Func& or rFunc

编辑从以下评论中回答以下问题:“为什么它们以这种方式排列”:无法复制函数(如@JohnBurger 的回答中所述)。 这就是为什么你的代码:

typedef void ( aFunc )();
aFunc af0 = theFunc;

不起作用。 如上所述,您可以执行以下操作:

typedef void ( aFunc )();
aFunc* af0 = &theFunc; // or theFunc, or even *theFunc

或者你可以这样做:

auto myFct = theFunc;

但请记住, myFctdecltype仍然是void (*)()

暂时忽略函数:考虑一个struct

你可以有一个struct ,或者一个指向struct的指针:

typedef struct {
    int x;
    int y;
} Point;

Point origin = { 0, 0 };
Point here   = { 1, 1 };
Point there  = { 2, 2 };

int main() {
   Point  centre  =  origin;
   Point *myPoint = &origin;

   centre  =  here;
   myPoint = &here;

   centre  =  there;
   myPoint = &there;
} // main()

共有三个全局Pointoriginherethere

main()有两个变量: centremyPoint

centre复制origin的值, herethere

myPoint点到originherethere -它不会复制它们。

这两种想法有很大的不同:一种复制整个对象,而另一种只指向另一个对象。

现在考虑函数。 函数由编译器在代码中定义,永远不能被复制。 所以拥有函数变量是没有意义的——它们会有多大? 唯一明智的想法是指向函数的指针——这就是 C 语言提供的全部内容。

如果要定义 C 函数typedef ,请使用以下语法:

// Fn is a function that accepts a char and returns an int
int Fn(char c);

// FnType is the type of a function that accepts a char and returns an int
typedef int FnType(char c);

// Here is the definition of Fn
int Fn(char c) {
    return c + 1;
} // Fn(c)

// Now here is how you can use FnType
int main() {
    FnType *fn = &Fn;
    return fn('A');
} // main()

我想我已经找到了答案。

实际上,c++ 标准提供了一种无需指针帮助即可声明函数类型的方法。

例子:

#include <functional>

using AFunc_t = function<void( int )>;

void theFunc( int );

AFunc_t afunc = theFunc;

我希望这可以帮助某人。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM