7.2参数传递
7.2.1非引用形参
普通的非引用类型的参数通过复制对应的实参实现初始化。
当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。
1指针形参
函数的形参可以是指针,此时将复制实参指针。与其他非引用类型的形参一样,该类形参的任何改变也仅作用于局部副本。
如果函数将新指针赋给形参,主调函数使用的实参指针的值没有改变。
事实上被复制的指针只影响对指针的赋值,如果函数形参是非const类型的指针,则函数可通过指针实现赋值,修改指针所指向对象的值
#include <iostream>
using namespace std;
void reset(int *p)
{
//*p = 1;
p = 0;
}
int main(void)
{
int a = 10;
reset(&a);
cout << a <<endl;
}
|
2 const形参
在调用函数时,如果该函数使用非引用的非const形参,则既可给该函数传递const实参也可传递非const的实参。
3复制实参的局限性
当需要在函数中修改实参的值时
当需要以大型对象作为实参传递时
当没有办法实现对象的复制时。
7.2.2引用形参
形参定义为引用类型
void swap(int &v1,int &v2)
{
}
|
引用形参直接关联到其所绑定的对象,而并非这些对象的副本。
定义引用时,必须用与该引用绑定的对象初始化该引用。引用形参完全以相同的方式工作。
每次调用函数,引用形参被创建并与相应实参关联。
1 使用引用形参返回额外的信息
vector<int>::const_iterator find_val(vector<int>::size_type &ocurs) {}
2 利用const引用避免复制
3 更灵活的指向const的引用
7.2.3 Vector和其他容器类型的形参
通常,函数不应该有vector或其他标准库容器类型的形参。调用含有普通的非引用vector形参的函数将会复制vector的每一个元素
从避免复制vector的角度出发,应考虑将形参声明为引用类型
7.2.4 数组形参
数组有二个特殊性质,影响我们定义和使用在数据上的函数:一是不能复制数组,二是使用数组名字时,数组名会自动转化为指向其第一个元素的指针
1 数组形参的定义
#include <iostream>
#include <string>
using namespace std;
void printValue1(int*)
{
}
void printValue2(int[])
{
}
void printValue3(int[10])
{
}
int main(void)
{
int *arr = {1,2,3,4,5};
printValue1(arr);
}
|
2 形参的长度会引起误解
3 数组实参
数组形参可以定义为引用或非引用类型。大部分情况下,数组以普通的非引用类型传递。而在传递数组时,实参是指向数组第一个元素的指针,形参复制的是这个指针的值,而不是数组元素本身。
4 通过引用传递数组
数组形参可声明为数组的引用。如果形参是数组的引用,编译器不会将数组实参转化为指针,而是传递数组的引用本身。
7.2.5 传递给函数的数组的处理
第一种方法:在数据本身放置一个标记来检测数组的结束。C风格字符串就是采用这种方法,它是一种字符数组,并且以空字符null作为结束的标记。
1 使用标准库规范
传递指向数组第一个和最后一个元素的下一个位置的指针
#include <iostream>
#include <string>
using namespace std;
void printValues(const int *beg,const int *end)
{
while(beg != end)
{
cout << *beg++ <<endl;
}
}
int main(void)
{
int arr[2] = {1,2};
printValues(arr,arr+2);
return 0;
}
|
2 显式传递表式数组大小的形式
#include <iostream>
#include <string>
using namespace std;
void printValues(const int ia[],size_t size)
{
for(int i=0; i != size;++i)
{
cout << ia[i] <<endl;
}
}
int main(void)
{
int arr[2] = {1,2};
printValues(arr,sizeof(arr) / sizeof(*arr));
return 0;
}
|
7.2.6 main处理命令行选项
7.3 return语句
7.3.1 没有返回值的函数
在返回类型为void的函数中,return返回语句不是必须的,隐式的return 发生在函数的最后一个语句完成时。
7.3.2 具有返回值的函数
1 主函数main的返回值
允许主函数main没有返回值就可结束。如果程序控制执行到主函数main的最后一个语句还没有返回,那么编译器会隐式地插入返回0的语句。
2 返回非引用类型
函数的返回值用于初始化在调用函数处创建的临时对象。
3 返回引用
当函数返回引用类型时,没有复制返回值。相反,返回的是对象本身。
const &shortString(const string &s1,const string &s2)
{
}
|
4 千万不要返回局部对象的引用
5 引用返回左值
6 千万不要返回指向局部对象的指针
7.4 函数声明
1 默认实参
默认实参是通过给形参表中的形参提供明确的初始值来指定的。
程序员可以为一个或多个形参定义默认值。但是,如果有一个形参具有默认实参,那么,它后面所有形参都必须有默认实参。
string screenInit(string::size_type height=24,string::size_type weight = 90 )
{
cout << height <<endl;
cout << weight <<endl;
return "success";
}
|
2 指定默认实参的约束
即可以在函数声明也可以在函数定义中指定默认实参。但是,在一个文件中,只能为一个形参指定默认实参一次。
7.5 局部对象
7.5.1自动对象
只有当定义它的函数被调用时才存在的对象称为自动对象。自动对象在每次调用函数时创建和撤销。
7.5.2静态局部对象
static局部对象,确保不迟于在程序执行流程第一次经过该对象的定义语句时进行初始化。这种对象一旦被创建,在程序结束前不会被撤销
7.6 内联函数
1 内联函数避免函数调用的开销
将函数指定为内联函数,就是将它在程序中的每个调用点上 内联地 展开。
inline const string &shortString(const string &s1,const string &s2){}
2 把内联函数放入头文件
在头文件中加入或修改内联函数时,使用了该头文件的所有源文件都必须重新编译。
7.7 类的成员函数
#include <iostream>
using namespace std;
class Sale {
public:
double avg_price() {
cout << "avg_price" <<endl;
return 100;
}
private:
string isbn;
double age;
};
int main()
{
Sale sale;
sale.avg_price();
return 0;
}
|
7.7.1 定义成员函数的函数体
1 成员函数含有额外的、隐含的形参
调用成员函数,实际上是使用对象来调用的。
2 this指针的引入
每个成员函数都有一个额外的、隐含的形参this。在调用成员函数时,形参this初始化为调用函数的对象的地址。
在调用成员函数时,形参this初始化为调用函数的对象的地址。
3 const成员函数的引入
由于this是指向const对象的指针,const成员函数不能修改调用该函数的对象。
const对象、指向const对象的指针或引用只能用于调用const成员函数,如果尝试用它们来调用非const成员函数,则是错误的。
4 this指针的使用
在成员函数中,不必显式的使用this指针来访问被调用函数所属对象的成员。对这个类的成员的任何没有前缀的引用,都被假定为通过指针this实现的引用。
7.7.2 在类外定义成员函数
1 构造函数是特殊的成员函数
2 构造函数的定义
3 构造函数的初始化列表
4 合成的默认构造函数
class Sale {
public:
Sale():age(10)
{
cout << age<< endl;
}
double avg_price() {
cout << "avg_price" <<endl;
return 100;
}
private:
string isbn;
double age;
};
|
7.7.4 类代码文件的组织
通常将类的声明放置在头文件中。大多数情况下,在类外定义的成员函数则置于源文件中
7.8 重载函数
出现在相同作用域中的二个函数,如果具有相同的名字而形参表不同,则称为重载函数
7.9 指向函数的指针
函数指针是指指向函数而非指向对象的指针。
bool (*pf) (const string &,const string &);
语句将pf声明为指向函数的指针,它所指向的函数带有二个const string &类型的形参和bool类型的返回值
*pf 二侧的圆括号是必须的
1 用typedef简单函数指针定义
typedef bool (*cmpFcn) (const string &,const string &);
该定义表示cmpFcn是一种指向函数的指针类型的名字。
该指针的类型为"指向返回bool类型并带有二个const string引用形参的函数的指针"
2 指向函数的指针的初始化和赋值
在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。
3 通过指针调用函数
指向函数的指针可用于调用它所指向的函数。可以不需要使用解引用操作符,直接通过指针调用函数。
#include <iostream>
#include <string>
using namespace std;
using std::string;
bool getLength(const string &a,const string &b)
{
cout << "function point" + a + " " + b <<endl;
return true;
}
int main(void)
{
typedef bool (*cmpFn) (const string &,const string &);
cmpFn fn = getLength;
fn("admin","root");
return 0;
}
|
4 函数指针形参
函数的形参可以是指向函数的指针。这种形参可以用以下二种形式编写。
void useBigger(const string &,const string &,bool(const string &,const string &));
void useBigger(const string &,const string &, bool (*)(const string &,const string &));
|
相关推荐
7. 类与对象:类是C++面向对象编程的基础,它封装了数据和操作数据的方法。对象是类的实例。练习题会涉及到类的设计、对象的创建和销毁、成员函数的使用,以及访问控制(public、private、protected)。 8. 继承与...
C++ Primer 习题解答首先会引导读者熟悉C++的基本语法,包括变量声明、数据类型(如整型、浮点型、字符型)、运算符(算术、关系、逻辑、位操作)、控制流(if语句、switch语句、循环结构for、while、do-while)以及...
7. **异常处理**:C++提供了异常处理机制,用于捕获和处理运行时错误。理解try、catch和throw语句的使用至关重要。 8. **STL(标准模板库)**:STL是C++标准库的一部分,包含容器、迭代器、算法和函数对象。熟悉STL...
《C++ Primer 中文第五版》是一本深受程序员喜爱的C++学习书籍,它全面而深入地介绍了C++编程语言的各个方面。这本书以其清晰的解释、丰富的实例和实用的建议,成为了初学者和有经验的程序员提升C++技能的重要参考...
此外,C++ Primer 5th还详细阐述了模板这一强大的工具,包括函数模板、类模板、模板特化和模板元编程。模板是C++中的泛型编程基础,能够实现代码的高效和灵活。 标准库是C++编程的重要组成部分,书中详细介绍了STL...
《C++ Primer中文版》是一本为初学者设计的C++编程教材,旨在帮助读者深入理解和掌握C++语言。这本书的高清版本提供了清晰的文本和图表,使得阅读体验更佳,尤其适合长时间学习和查阅。目录的存在使得学习者能够快速...
《C++ Primer》是C++编程领域的一本经典著作,第五版更是深受程序员喜爱的教程。这本书详尽地介绍了C++语言,从基础语法到高级特性,为读者提供了全面而深入的学习路径。作为英文版,它保持了原汁原味的专业表达,...
7. **STL(Standard Template Library)**:C++标准库中的模板容器、算法和迭代器等组件,提供了高效且易用的数据结构和算法。 8. **异常处理**:C++支持异常处理机制,通过try、catch和throw关键字来捕获和处理...
C++ Primer 中文版勘误表 C++ Primer 是一种广泛使用的 C++ 编程语言教程书籍,而中文版的 C++ Primer 也存在一些小错误。以下是 C++ Primer 中文版勘误表,总结了书中的一些错误和修订内容。 1. 第 79 页表 3-4 ...
7. **异常处理**:C++提供了一种结构化的错误处理机制——异常处理。通过try、catch和throw关键字,程序员可以优雅地处理运行时错误。 8. **C++11新特性**:第五版涵盖了C++11标准引入的新特性和改进,如auto关键字...
《C++ Primer》是有名的C++编程教材,其第五版(5th Edition)深入浅出地介绍了C++语言的基础知识以及C++11新标准的特性。这本书由Lippman、Lajoie和 Moo三位作者共同编写,是C++初学者和进阶者的重要参考书籍。 1....
此外,C++ Primer还涵盖了泛型编程和模板,包括函数模板、类模板以及模板特化。模板是C++中实现代码重用的强大工具,可以创建通用的算法和数据结构。 标准库是C++编程不可或缺的一部分,书中详细讲解了iostream库...
《C++ Primer 第四版》是著名的C++编程语言教程,由Stanley B. Lippman、Josée Lajoie和Barbara E. Moo三位作者共同撰写。该书自出版以来,已成为广大程序员学习C++的必备书籍。第四版对前三版的内容进行了彻底的...
1. C++基础语法与程序结构:文件提到了C++程序的基本结构,包括main函数的定义、输入输出流的使用、变量的声明、标准库头文件的包含等。例如,使用#include来包含标准输入输出流库,以及main函数的返回类型int。 2....
《C++ Primer Plus》是一本深受程序员喜爱的C++学习书籍,它深入浅出地介绍了C++编程语言的基础和高级特性。课后习题是学习过程中不可或缺的一部分,它们旨在帮助读者巩固理论知识,提高实际编程技能。这个压缩包...
7. **模板**:模板是C++的泛型编程工具,允许创建泛化的函数和类。理解函数模板、类模板以及模板特化是进阶C++的关键。 8. **STL(标准模板库)**:包括容器(如map、set、list)、迭代器、算法和函数对象,是C++...
此外,描述中提及的“真正的C++primer习题集”,这可能表明该习题集是针对教材内容设计的,目的是帮助学生消化和练习书中的理论知识。通过解决这些习题,学生可以加深对C++语言特性的理解,包括类和对象、动态内存...
通过这些练习,读者可以进一步熟悉C++编程的各个方面,包括但不限于基本语句、数据类型、控制结构、函数、类和标准库的使用。 此外,习题解答中所使用的开发环境为Visual Studio 2015,这是微软推出的一款集成开发...