精华内容
下载资源
问答
  • 怎样重载一个函数

    2013-05-24 20:04:56
    一个函数名在一个特殊的域中被声明多次时,编译器按如下步骤解释第二个(以及后续的)的声明: 1、如果两个函数的参数表中参数的个数或类型不同,则认为这两个函数是重载的。例如:  //重载函数  void print...

    当一个函数名在一个特殊的域中被声明多次时,编译器按如下步骤解释第二个(以及后续的)的声明:

    1、如果两个函数的参数表中参数的个数或类型不同,则认为这两个函数是重载的。例如:

          //重载函数

          void print(const string &) ;

          void print(vector<int> &) ;

    2、如果两个函数的返回类型和参数表精确匹配,则第二个声明被视为第一个的重复声明。例如:

          //声明同一个函数

          void print(const string &str) ;

          void print(const string &) ;

    这说明参数表的比较过程与参数名无关

    3、如果两个函数的参数表相同,但是返回类型不同,则第二个声明被视为第一个的错误重复声明,会被标记为编译错误。例如:

          unsigned int max(int i1, int i2) ;

          int max(int, int) ;   //错误,只有返回类型不同

    这说明函数的返回类型不足以区分两个重载函数。

    4、如果在两个函数的参数表中,只有缺省实参不同,则第二个声明被视为第一个的重复声明。例如:

          //声明同一个函数

          int max(int *ia,int sz) ;

          int max(int *, int  = 10)  ;

    5、如果两个函数的参数表中,参数类型是const或volatitle时,识别函数声明是否相同时,并不考虑const或volatitle修饰符。例如,下列两个声明声明了同一个函数:

          //声明同一个函数

          void f( int ) ;

          void f( const int ) ;

           参数是const,这只跟函数的定义有关系:它意味着,函数体内的表达式不能改变参数的值。但是,对于按值传递的参数,这对函数的用户是完全透明的:用户不会看到函数对按值传递的实参的改变。但实参被按值传递时,将参数声明为const不会改变可以被传递该函数的实参的种类。任何int型的实参都可以被用来调用函数f(const int)。因为两个函数接收相同的实参集,所以刚才给出的两个声明没有声明一个重载函数。

    但是,如果把const或volatitle应用在指针或引用参数指向的类型上,则在判断函数声明是否相同时,就要考虑const和volatitle修饰符。

           //声明了两个不同的函数

              void f( int* ) ;

              void f( const int * ) ;

           //也声明了两个不同的函数

              void f( int& ) ;

              void f(const int &) ;

     

     

    展开全文
  • 一个函数名在一个特殊的域中被声明多次时,编译器按如下步骤解释后续的声明。 (1)如果两个函数的参数表中的参数的个数或类型不同,则认为是重载的。例如: void print(const string&); void print...

    在C++中,可以为两个或多个函数提供相同的名字,只要它们的每个参数表唯一就行:或者是参数的个数不同,或者是参数类型不同。

    当一个函数名在一个特殊的域中被声明多次时,编译器按如下步骤解释后续的声明。

    (1)如果两个函数的参数表中的参数的个数或类型不同,则认为是重载的。例如:

    void print(const string&); void print(vector<int> &);(2)如果两个函数的返回类型和参数表精确匹配,则第二个声明被视为第一个的重复声明。

    void print(const string &str); void print(const string &);

    参数表的比较过程和参数名无关。

    (3)如果两个函数的参数表相同,但是返回类型相同,则第二个声明被视为第一个的错误声明,会被标记为编译错误。例如:

    unsigned int max(int i1,int i2); int max(int ,int );函数的返回类型不足以区分两个重载函数。

    (4)如果在两个函数的参数表中,只有缺省实参不同,则第二个声明被视为第一个的重复声明。例如:

    int max(int* ia,int sz); int max(int*,int = 10);


    Note1:如果两个参数表的区别只在于一个使用了typedef,而另一个使用了与typedef相应的类型,则该参数表不被视为不同。


    Note2:当一个参数类型是const或者volatile时,在识别函数是否相同时,并不考虑const和volatile。例如,下列两个声明声明了同一个函数:

    void f(int); void f(const int);参数是const,这只跟函数的定义有关系:它意味着,函数体内的表达式不能改变参数的值。但是,对于按值传递的参数,这对函数的用户是完全透明的:用户不会看到函数对按值传递的实参的改变。将参数声明为const不会改变可以被传递给该函数的实参种类。任何int型的实参都可以被用来调用函数f(const int)。

    但是,如果吧const或volatile应用在指针或者引用参数指向的类型上,则在判断函数声明是否相同时,就要考虑const和volatile修饰符。

    例如:

    //声明了不同的函数 void f(int*); void f(const int*); //也声明了不同的函数 void f(int&); void f(const int&);

    Note3:链接指示符extern "C"只能指定重载函数集中的一个函数。例如:包含下列两个声明的程序时非法的:

    extern "C" void print(const char*); extern "C" void print(int);这主要是由于类型安全链接的问题。

    大多数编译系统的底层组件要求每个函数名必须唯一,这是因为大多数链接编辑器都是按照函数名来解析外部引用的。为处理这个问题,每个函数名及其相关参数表都被作为一个唯一的内部名编码(encoded)。编译系统的底层组件只能看到编码后的名字。因为这种编码帮助链接阶段区分程序中的重载函数,所以我们把它称为类型安全链接

    这种特殊的编码不适合用户用链接指示符extern "C"声明的函数。这就是为什么在重载函数集合中只有一个函数可以被声明为extern "C"的原因,具有不同的参数表的两个函数会被编辑器视为同一函数。

    转载于:https://www.cnblogs.com/xiajun/archive/2011/09/05/2298649.html

    展开全文
  • 例如声明了vector<string> vecstr 怎样在构造函数中显示初始化?
  • 但在实际操作中,并没有调用到FiveScene类下面的init()函数,求教应该怎么变动 (编译已通过,部分相关代码如下) mainwindow.h(已经#include "fivescene.h") namespace Ui { class MainWindow; } class FiveScene...
  • 函数表达式在 JavaScript 中,函数不是“神奇的语言结构”,而是一种特殊的值。我们在前面章节使用的语法称为 函数声明:function sayHi() { alert( ...在这里,函数被创建并像其他赋值一样,被明确地分配给了一个变...

    函数表达式

    在 JavaScript 中,函数不是“神奇的语言结构”,而是一种特殊的值。

    我们在前面章节使用的语法称为 函数声明

    function sayHi() { alert( "Hello" );}

    另一种创建函数的语法称为 函数表达式

    通常会写成这样:

    let sayHi = function() { alert( "Hello" );};

    在这里,函数被创建并像其他赋值一样,被明确地分配给了一个变量。不管函数是被怎样定义的,都只是一个存储在变量 sayHi 中的值。

    上面这两段示例代码的意思是一样的:“创建一个函数,并把它存进变量 sayHi”。

    我们还可以用 alert 打印这个变量值:

    function sayHi() { alert( "Hello" );}alert( sayHi ); // 显示函数代码

    注意,最后一行代码并不会运行函数,因为 sayHi 后没有括号。在其他编程语言中,只要提到函数的名称都会导致函数的调用执行,但 JavaScript 可不是这样。

    在 JavaScript 中,函数是一个值,所以我们可以把它当成值对待。上面代码显示了一段字符串值,即函数的源码。

    的确,在某种意义上说一个函数是一个特殊值,我们可以像 sayHi() 这样调用它。

    但它依然是一个值,所以我们可以像使用其他类型的值一样使用它。

    我们可以复制函数到其他变量:

    function sayHi() { // (1) 创建 alert( "Hello" );}let func = sayHi; // (2) 复制func(); // Hello // (3) 运行复制的值(正常运行)!sayHi(); // Hello // 这里也能运行(为什么不行呢)

    我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我的头条号并在后台私信我:前端,即可免费获取。

    解释一下上段代码发生的细节:

    1. (1) 行声明创建了函数,并把它放入到变量 sayHi。
    2. (2) 行将 sayHi 复制到了变量 func。请注意:sayHi 后面没有括号。如果有括号,func = sayHi() 会把 sayHi() 的调用结果写进func,而不是 sayHi 函数 本身。
    3. 现在函数可以通过 sayHi() 和 func() 两种方式进行调用。

    注意,我们也可以在第一行中使用函数表达式来声明 sayHi:

    let sayHi = function() { alert( "Hello" );};let func = sayHi;// ...

    这两种声明的函数是一样的。


    为什么这里末尾会有个分号?

    你可能想知道,为什么函数表达式结尾有一个分号 ;,而函数声明没有:

    function sayHi() { // ...}let sayHi = function() { // ...};

    答案很简单:

    • 在代码块的结尾不需要加分号 ;,像 if { ... },for { },function f { } 等语法结构后面都不用加。
    • 函数表达式是在语句内部的:let sayHi = ...;,作为一个值。它不是代码块而是一个赋值语句。不管值是什么,都建议在语句末尾添加分号 ;。所以这里的分号与函数表达式本身没有任何关系,它只是用于终止语句。

    回调函数

    让我们多举几个例子,看看如何将函数作为值来传递以及如何使用函数表达式。

    我们写一个包含三个参数的函数 ask(question, yes, no):

    question:关于问题的文本

    yes:当回答为 "Yes" 时,要运行的脚本

    no:当回答为 "No" 时,要运行的脚本

    函数需要提出 question(问题),并根据用户的回答,调用 yes() 或 no():

    function ask(question, yes, no) { if (confirm(question)) yes() else no();}function showOk() { alert( "You agreed." );}function showCancel() { alert( "You canceled the execution." );}// 用法:函数 showOk 和 showCancel 被作为参数传入到 askask("Do you agree?", showOk, showCancel);

    在实际开发中,这样的的函数是非常有用的。实际开发与上述示例最大的区别是,实际开发中的函数会通过更加复杂的方式与用户进行交互,而不是通过简单的 confirm。在浏览器中,这样的函数通常会绘制一个漂亮的提问窗口。但这是另外一件事了。

    ask 的 showOk 和 showCancel 两个 arguments 对象可以被称为 回调函数 或简称 回调

    主要思想是我们传递一个函数,并期望在稍后必要时将其“回调”。在我们的例子中,showOk 是回答 "yes" 的回调,showCancel 是回答 "no" 的回调。

    我们可以用函数表达式对同样的函数进行大幅简写:

    function ask(question, yes, no) { if (confirm(question)) yes() else no();}ask( "Do you agree?", function() { alert("You agreed."); }, function() { alert("You canceled the execution."); });

    这里直接在 ask(...) 调用内进行函数声明。这两个函数没有名字,所以叫 匿名函数。这样的函数在 ask 外无法访问(因为没有对它们分配变量),不过这正是我们想要的。

    这样的代码在我们的脚本中非常常见,这正符合 JavaScript 语言的思想。


    一个函数是表示一个“动作(action)”的值

    字符串或数字等常规值代表 数据

    函数可以被视为一个 动作

    我们可以在变量之间传递它们,并在需要时运行。


    函数表达式 vs 函数声明

    让我们来总结一下函数声明和函数表达式之间的主要区别。

    首先是语法:如何通过代码对它们进行区分。

    • 函数声明:在主代码流中声明为单独的语句的函数。 // 函数声明 function sum(a, b) { return a + b; } 复制代码
    • 函数表达式:在一个表达式中或另一个语法结构中创建的函数。下面这个函数是在赋值表达式 = 右侧创建的: // 函数表达式 let sum = function(a, b) { return a + b; }; 复制代码

    更细微的差别是,JavaScript 引擎会在 什么时候 创建函数。

    函数表达式是在代码执行到达时被创建,并且仅从那一刻起可用。

    一旦代码执行到赋值表达式 let sum = function… 的右侧,此时就会开始创建该函数,并且可以从现在开始使用(分配,调用等)。

    函数声明则不同。

    在函数声明被定义之前,它就可以被调用。

    例如,一个全局函数声明对整个脚本来说都是可见的,无论它被写在这个脚本的哪个位置。

    这是内部算法的原故。当 JavaScript 准备 运行脚本时,首先会在脚本中寻找全局函数声明,并创建这些函数。我们可以将其视为“初始化阶段”。

    在处理完所有函数声明后,代码才被执行。所以运行时能够使用这些函数。

    例如下面的代码会正常工作:

    sayHi("John"); // Hello, Johnfunction sayHi(name) { alert( `Hello, ${name}` );}

    函数声明 sayHi 是在 JavaScript 准备运行脚本时被创建的,在这个脚本的任何位置都可见。

    ……如果它是一个函数表达式,它就不会工作:

    sayHi("John"); // error!let sayHi = function(name) { // (*) no magic any more alert( `Hello, ${name}` );};

    函数表达式在代码执行到它时才会被创建。只会发生在 (*) 行。为时已晚。

    函数声明的另外一个特殊的功能是它们的块级作用域。

    严格模式下,当一个函数声明在一个代码块内时,它在该代码块内的任何位置都是可见的。但在代码块外不可见。

    例如,想象一下我们需要依赖于在代码运行过程中获得的变量 age 声明一个函数 welcome()。并且我们计划在之后的某个时间使用它。

    如果我们使用函数声明,以下则代码不能如愿工作:

    let age = prompt("What is your age?", 18);// 有条件地声明一个函数if (age < 18) { function welcome() { alert("Hello!"); }} else { function welcome() { alert("Greetings!"); }}// ……稍后使用welcome(); // Error: welcome is not defined

    这是因为函数声明只在它所在的代码块中可见。

    下面是另一个例子:

    let age = 16; // 拿 16 作为例子if (age < 18) { welcome(); //  (运行) // | function welcome() { // |  alert("Hello!"); // | 函数声明在声明它的代码块内任意位置都可用 } // |  // | welcome(); // / (运行)} else { function welcome() { alert("Greetings!"); }}// 在这里,我们在花括号外部调用函数,我们看不到它们内部的函数声明。welcome(); // Error: welcome is not defined

    我们怎么才能让 welcome 在 if 外可见呢?

    正确的做法是使用函数表达式,并将 welcome 赋值给在 if 外声明的变量,并具有正确的可见性。

    下面的代码可以如愿运行:

    let age = prompt("What is your age?", 18);let welcome;if (age < 18) { welcome = function() { alert("Hello!"); };} else { welcome = function() { alert("Greetings!"); };}welcome(); // 现在可以了

    或者我们可以使用问号运算符 ? 来进一步对代码进行简化:

    let age = prompt("What is your age?", 18);let welcome = (age < 18) ? function() { alert("Hello!"); } : function() { alert("Greetings!"); };welcome(); // 现在可以了

    什么时候选择函数声明与函数表达式?

    根据经验,当我们需要声明一个函数时,首先考虑函数声明语法。它能够为组织代码提供更多的灵活性。因为我们可以在声明这些函数之前调用这些函数。

    这对代码可读性也更好,因为在代码中查找 function f(…) {…} 比 let f = function(…) {…} 更容易。函数声明更“醒目”。

    ……但是,如果由于某种原因而导致函数声明不适合我们(我们刚刚看过上面的例子),那么应该使用函数表达式。


    总结

    • 函数是值。它们可以在代码的任何地方被分配,复制或声明。
    • 如果函数在主代码流中被声明为单独的语句,则称为“函数声明”。
    • 如果该函数是作为表达式的一部分创建的,则称其“函数表达式”。
    • 在执行代码块之前,内部算法会先处理函数声明。所以函数声明在其被声明的代码块内的任何位置都是可见的。
    • 函数表达式在执行流程到达时创建。

    在大多数情况下,当我们需要声明一个函数时,最好使用函数声明,因为函数在被声明之前也是可见的。这使我们在代码组织方面更具灵活性,通常也会使得代码可读性更高。

    所以,仅当函数声明不适合对应的任务时,才应使用函数表达式。在本章中,我们已经看到了几个例子,以后还会看到更多的例子。

    049989e25a5d57f6f4759d28dcb22248.png


    作者:技术漫谈
    链接:https://juejin.im/post/5dddd1b5f265da060f24f34c

    展开全文
  • 一个全局变量或函数可以 (在多个编译单元中) 有多处 “声明”, 但是 “定义” 却只能允许出现一次。 定义是分配空间并赋初值 (如果有) ,声明则是给需要调用该变量或者函数的地方声明该变量或函数,使编译不出错。...

            一个全局变量或函数可以 (在多个编译单元中) 有多处 “声明”, 但是 “定义” 却只能允许出现一次。

            定义是分配空间并赋初值 (如果有) ,声明则是给需要调用该变量或者函数的地方声明该变量或函数,使编译不出错。

         最好的安排是在某个相关的 .c 文件中定义, 然后在其对应的头文件 (.h)(用extern
    修饰) 中进行外部声明, 在需要使用的时候, 只要包含对应的头文件即可。定义变量的 
    .c 文件也应该包含该头文件, 以便编译器检查定义和声明的一致性。


     

    展开全文
  • 的变量声明,下面就来介绍这种变量声明的理解规律: 想看懂这种变量声明,首先得学会右左法则;  就是先找到变量,再寻找变量右边的提示再看左边再右边一直循环; 注:  * 代表指针;  【】代表数组;  ...
  • 一、在VB中声明API函数有两种方法:如果我们只在某个窗体中使用API函数,我们可以在窗体代码的General部分声明它: ... 这里必须采用Private声明,因为这个API函数只能被一个窗体内的程序所调用。 如果我们的程序有多个
  • 函数声明

    2014-06-04 08:46:16
    看了C陷阱与缺陷,第一个给我震撼的就是理解函数声明了,下面是我的理解。 1.理解函数声明  为了模拟开机启动时的情形,我们必须设计出一个C语句,以显示调用...那么,要想声明一个函数指针,指向这类函数,怎样
  • 一、在VB中声明API函数有两种方法:如果我们只在某个窗体中使用API函数,我们可以在窗体... 这里必须采用Private声明,因为这个API函数只能被一个窗体内的程序所调用。 如果我们的程序有多个窗体构成,而且我们需要在
  • 当类中声明函数时,编译器会在类中生成一个函数表。虚函数表是一个存储成员函数指针的数据结构,它是由编译器自动生成与维护的,virtual成员函数会被编译器放入虚函数表中。 所以,当存在虚函数时,每个对象都...
  • 声明一个函数 // 普通函数的写法 let fn = function (a,b){ return a+b; } // 箭头函数的写法 let fn = (a,b) => {return a+b;} 调用则是和普通函数一样 fn(6,7); 箭头函数的特性 this 是静态的 this始终...
  • 那么它究竟是一个怎样函数呢?我努力回忆起《C专家编程》一书的内容,把其中解读变量声明的方法应用于该函数上,最终读懂了该函数。下面是大致的解读过程。首先,要确定声明中出现的操作符的优先级。显然,函数...
  • C语言中的函数声明

    千次阅读 2012-03-07 23:07:32
    看了C陷阱与缺陷,第一个给我震撼的就是理解函数声明了,下面是我的理解。 1.理解函数声明  为了模拟开机启动时的情形,我们必须设计出一个C语句,以显示调用...那么,要想声明一个函数指针,指向这类函数,怎样声明
  • 怎样利用常成员函数

    千次阅读 2010-06-22 16:26:00
    <br />(1) 如果在一个类中,有些数据成员的值允许改变,另一些数据成员的值不允许改变,则可以将一部分数据成员声明为const,以保证其值不被改变,可以用非const的成员函数引用这些数据成员的值,并修改非...
  • 怎样使用C++回调函数

    2012-07-23 14:41:41
    程序员常常需要实现回调... 回调函数一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法
  • 输入理解C语言中的函数声明

    千次阅读 2009-11-19 21:37:00
    看了C陷阱与缺陷,第一个给我震撼的就是理解函数声明了,下面是我的理解。1.理解函数声明 为了...首先我们从函数的声明说起:有如下一个函数 void func(){...}那么,要想声明一个函数指针,指向这类函数,怎样声明
  • 那么它究竟是一个怎样函数呢?我努力回忆起《C专家编程》一书的内容,把其中解读变量声明的方法应用于该函数上,最终读懂了该函数。下面是大致的解读过程。   首先,要确定声明中出现的操作符的优先级。...
  • 因为在子类不能 直接使用 _属性名的父类的属性默认生成的实例便量,但是在子类的方法之中使用@synthesize 可以对继承过来的属性进行声明一个_属性名 名字的变量(这个变量到底是父类继承过来的还是在子类新生成的 父类...
  • 在c++中,声明一个变量或者函数是怎么确定的,例如下面的代码: class A; A f(); 可以理解为创建一个A类的f对象,使用默认构造函数。 还可以理解为声明一个返回为A 类型,传入参数为空的f函数。 这个貌似一般都不会...
  • 1、声明一个接口,只能包含一个抽象方法 2、给这个接口加@FunctionalInterface 例1: //1、定义一个函数式接口IntCalc,其中抽象方法int cal(int a , int b),使用注解@FunctionalInterface @FunctionalInterface ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 657
精华内容 262
关键字:

怎样声明一个函数