C++ primer 第七章笔记总结

本文是C++ Primer第七章的学习笔记,重点介绍了函数的定义、参数传递、返回值、函数声明、成员函数、构造函数以及重载函数的概念。强调了形参表、函数体的作用域、引用形参在避免大型对象复制中的应用,以及函数指针的使用。
摘要由CSDN通过智能技术生成

看完C++ Primer的第七章,觉得这一章值得被一看再看,现写了一些总结,尽量囊括知识点,但绝不冗余,力求简单易懂。

第七章的题目是 函数

定义:

int  add ( int  x, int  y) {}

前面的int为返回参数类型。函数在定义时必须声明函数的返回类型(除了类的构造函数以及析构函数)

add 是函数名,同时也是函数的地址。(这一句很重要):

括号内 是形参表,其中的形参便是在这里定义,在函数调用时进行初始化的。

{}内是函数体。函数体本身是构成一个作用域。遵循作用域的原则。


参数传递:

非引用形参:对形参初始化之后,实参就没事干了。函数体的操作都是形参的事。

1    指针形参:指针的值(某个东西的地址)赋给形参之后,就相当于把实参指向的东西的地址给了形参,形参就去操作指针指向的值了。如果参数有const,那么就不允许修改。

例如:

void changePtrTo(int *p)
{
     *p = 1; //p出卖了指向的值的地址(即它自身的值),指向的值被改变啦
       p = 0; //p本身却没有变
}
对于加入 const 的参数,说明函数内部不能修改该形式参数的值(因为是传值调用),因此传给它const 或者是非const都可以。


但是,在  需要修改实参的值  、 实参的对象比较大,复制很耗时、没有办法实现对象的复制时,引入了引用形参。


引用形参:

当函数要返回两个内容的时候,可以将一个内容的指针或者是引用作为形参。

避免大型对象的复制。


其他形参:

vector   或者其他容器类型     ,为了避免,可以直接将该容器的起始与结尾的迭代器作为参数。

数组形参: 数组会退化为指针,指向数组头结点的指针。通常直接将数组名当做指针传入。如果指定了指针的长度,C++编译器会直接忽略不管,因此下述3种定义是等价的:

void   Func(int *a);
void   Func(int a[]);
void   Func(int a[10]);

但是如果传递的是数组的引用,那么数组名就不会退化为指针,而是当做数组来处理,如:
void   Func(int (&arr)[10] );//该函数只接收数组大小为10的数组!!

对于多维数组的传递,跟定义一样,指明第二维 的大小即可。


对于参数的数目是可变的,void foo(parm_list,...),用三个点即可。


函数的返回值:

main函数的返回值,建议使用不依赖于机器的 EXIT_SUCCESS与EXIT_FAILURE.

返回非引用类型,创建一个临时对象返回,返回调用处即可。

返回引用类型。(不可返回局部对象的引用或者是指向局部对象的指针)

返回左值(竟然还有这样的!!) 

int getElem(int A[], int index)
{
  return A[index];
}

上述函数返回的是数组的元素,因此可以有 getElem(A, 2 ) = 5;表示将数组的第2个元素赋值为5.


函数声明:

默认实参 :

int add(int x, int y = 0,  int z = 3); //默认实参的位置必须是参数表的某后缀!!!

注意:默认实参只能在函数声明和函数定义中 出现一次。


类的成员函数:

定义在函数体内部的,自动编译为内联函数。

每一个类的成员函数都有一个隐式的参数this指针。指的是调用这个函数的对象的地址。(除static之外)

常成员函数,就是在函数声明的某位加上const,表示调用该函数的对象不可以被修改。


构造函数:

与类同名、 无返回值、不同的构造函数应该有不同的类型或数目的形参。

没有参数的构造函数叫做默认构造函数。

如果没有定义构造函数,编译器会自动生成一个 “合成默认构造函数”,类内部的成员变量按照自己的初始化方式进行初始化。(次初始化的方式取决于该对象的定义的位置。全局/局部)。


重载函数

相同作用域下的两个函数,同名字但是形参表不同。

main不能重载。


下面的几种情况都不能称为重载:

int add(int x);
int add(int); //函数在调用时只会检查形参的类型,形参名是会被忽略的。
typedef unsigned char BYTE;
int add(unsigned char);
int add(BYTE ); //两者的形参类型是完全一致的
int add(int x, int y = 3);
int add(int x, int y);//第一个函数有默认参数,但是它的调用时包含了第二种情况的
int add(int x);
int add(const int x);//const不能作为重载的标志。(但是这仅限于非引用类型)

对于const的引用类型以及指向const的指针作为形参时,const是可以作为重载的标志的。


函数匹配:
当调用某个重载函数时,究竟调用哪个。取决于:1    每个实参的匹配都优于其他的候选者。或者是  2  至少有一个实参的匹配优于候选者。


实参匹配优先级:

精确匹配 -- >  类型提升 -->标准转换 -- > 类类型转换。


int  (*pAdd) (int , int);
将函数名处替换为指针表示即可,与定义int型指针式一样的,比如:

int x;
int *p;

int add(int ,int);
int (*pAdd)(int , int);

由于函数名实际上是函数的地址,因此可以用函数名初始化函数指针。

pAdd = add;

函数指针可以作为函数的参数,还可以作为返回值。

int (*ff(int))(int *, int);

指向重载函数的指针,由于重载本身的不确定性,因此要求实参与形参的匹配必须是精确匹配。


完毕!觉得这一章的东西主要是围绕函数来进行的。读完此章,获益匪浅。











  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值