美文网首页Cpp/C++
C++ 函数的一些重点

C++ 函数的一些重点

作者: Jimmy_L_Wang | 来源:发表于2018-10-18 11:35 被阅读9次

函数的引用参数使用

通过引用传递参数

一般函数,如:

int addition (int a, int b)
{
  int r;
  r=a+b;
  return r;
}

...

int x=5, y=3, z;
z = addition ( x, y );

其参数总是按值传递。这意味着,在调用函数时,传递给函数的是调用时这些参数的值,这些值被复制到函数表示的变量中。

在这种情况下,函数不是传递5和3,而是拷贝了x和y的副本。这些值(5和3)用于初始化函数定义中的参数,但函数中这些变量的任何修改都不会影响其外部的变量x和y的值,因为x和y是它们本身没有传递给调用函数,而只是那一刻它们的值的副本。

void duplicate (int& a, int& b, int& c)
{
  a*=2;
  b*=2;
  c*=2;
}

当通过引用传递变量时,传递的内容不再是副本,而是变量本身(由函数参数标识的变量)以某种方式与传递给函数的参数相关联,并且对其中对应的局部变量进行任何修改该函数反映在调用中作为参数传递的变量中

基于效率考量来使用引用参数

使用带值的参数调用函数会导致值的副本生成。对于诸如此类的基本类型,这是相对小的开销,但是如果参数是大型复合类型,则可能导致某些内存开销巨大。如:

string concatenate (string a, string b)
{
  return a+b;
}

此函数将两个字符串作为参数(按值),并返回连接它们的结果。通过按值传递参数,函数强制a并b成为调用时传递给函数的参数的副本。如果这些是长字符串,则可能意味着仅为函数调用复制大量数据。

但是,如果两个参数都被引用,则可以完全避免此副本的生成:

string concatenate (string& a, string& b)
{
  return a+b;
}

引用参数不需要副本。该函数直接对作为参数传递的字符串(别名)进行操作,并且最多可能意味着将某些指针传递给该函数。在这方面,concatenate获取引用的版本比获取值的版本更有效,因为它不需要复制昂贵的复制字符串。

另一方面,具有引用参数的函数通常被视为会修改传递的参数。

解决方案是使函数保证其参数参数不会被此函数修改。这可以通过将参数限定为常量来完成:

string concatenate (const string& a, const string& b)
{
  return a+b;
}

过限定它们const,该函数被禁止修改既不ab,也可以实际访问它们的值作为引用(参数的别名),而不必生成字符串的实际副本。

内联函数

调用函数通常会导致一定的开销(堆栈参数,跳转等等),因此对于非常短的函数,简单地插入它的函数的代码比调用函数可能更有效。

在使用说明inline之前的函数声明通知编译器内联扩展优先于特定函数的一般函数调用机制。这并不会改变函数的所有行为,而只是用于建议编译器函数体生成的代码应该在调用函数的每个点插入,而不是通过常规函数调用来调用。

例如,内联声明为:

inline string concatenate (const string& a, const string& b)
{
  return a+b;
}

Lambda 函数与表达式

C++11 提供了对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。

Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。

Lambda 表达式本质上与函数声明非常类似。

[capture](parameters)->return-type{body}
[](int x, int y){ return x < y ; }

[](int x, int y) -> int { int z = x + y; return z + x; }

在Lambda表达式内可以访问当前作用域的变量,这是Lambda表达式的闭包(Closure)行为。 与JavaScript闭包不同,C++变量传递有传值和传引用的区别。可以通过前面的[]来指定:

[]      // 沒有定义任何变量。使用未定义变量会引发错误。
[x, &y] // x以传值方式传入(默认),y以引用方式传入。
[&]     // 任何被使用到的外部变量都隐式地以引用方式加以引用。
[=]     // 任何被使用到的外部变量都隐式地以传值方式加以引用。
[&, x]  // x显式地以传值方式加以引用。其余变量以引用方式加以引用。
[=, &z] // z显式地以引用方式加以引用。其余变量以传值方式加以引用。

另外有一点需要注意。对于[=][&]的形式,lambda 表达式可以直接使用 this 指针。但是,对于[ ]的形式,如果要使用 this 指针,必须显式传入:

[this]() { this->someFunc(); }();

这通知编译器在concatenate调用时,程序更喜欢内联扩展功能,而不是执行常规调用。inline仅在函数声明中指定,而不是在调用时指定。

请注意,大多数编译器已经优化了代码,以便在他们看到提高效率的机会时生成内联函数,即使没有使用inline符明确标记。因此,此说明符仅指示编译器内联是此函数的首选,尽管编译器可以自由地不内联它,否则优化。在C++中,优化是委托给编译器的任务,只要生成的行为是代码指定的行为,就可以自由生成任何代码。

相关文章

  • C++ 函数的一些重点

    函数的引用参数使用 通过引用传递参数 一般函数,如: 其参数总是按值传递。这意味着,在调用函数时,传递给函数的是调...

  • windows逆向3

    VC 程序内存和编译的一些特征C++ 构造函数C++ 成员函数C++ 析构函数C++ 全局对象的构造C++ 全局对...

  • 数据排序

    前言 这次会介绍一些排序的方法,有些我会只说方法,思路。重点讲c++自带函数sort这篇文章不会涉及快排,因为写快...

  • GeekBand C++第二次课

    这一次课的重点,是讲解了C++四大函数:构造函数,析构函数,以及拷贝构造函数和拷贝赋值函数。基本知识点,我想不用再...

  • deleted function

    C++会给类型生成一些默认函数:默认构造函数、复制构造函数、赋值函数等等。如果你不想要这些函数,比如你的类型没有复...

  • 第八章 函数探幽(1)c++内联函数

    c++赋予了一些新的关于函数的特性,包括,内联函数,按引用传递变量,默认的参数值,函数重载(多态),以及模板函数...

  • C++ RAII类

    利用C++的构造函数和析构函数来做一些自动处理自动创建,自动消失 很好的选择

  • C++利用函数指针实现函数式编程的方法

    C++支持函数式编程,虽然使用的较少,下面列出一些用法: 普通函数作为回调普通函数作为输入参数的高阶函数 是最基本...

  • 一些函数

    cmp函数 C++ sort cmp函数 - lzz的博客 - CSDN博客 浅谈C/C++排序函数中cmp()比...

  • Python调用C++函数(SWIG,VS2013使用numpy

    最近尝试使用Python调用C++函数,发现网上都是一些简单的例子,涉及到Python Numpy数组与C++数组...

网友评论

    本文标题:C++ 函数的一些重点

    本文链接:https://www.haomeiwen.com/subject/uwpjzftx.html