一、 内联函数(inline)
宏函数(带参数的宏)出现的问题
- 在c中也会出现,宏看起来像一个函数调用,但是会有隐藏一些难以发现的错误;
C++
特有的,预处理器不允许访问类的成员,也就是说预处理器宏不能作类的成员函数
内联函数
内联函数为了继承宏函数的效率,没有函数调用时的开销,然后又可以像普通函数那样,可以进行参数、返回值类型的安全检查,又可以作为成员函数。
内联函数是一个真正的函数。
内联函数会在适当的地方像宏一样展开。 发生在编译阶段。
在函数定义处使用 inline
。
以空间换时间。
在类内部定义的函数自动成为内联函数!
条件:
- 不能存在任何形式的循环语句
- 不能存在过多的条件判断语句
- 函数体不能过于庞大不能对函数进行取址操作
内联函数仅仅是对编译器的建议。
二、函数的默认参数
C++
在声明函数原型时可为一个或多个参数指定默认(缺省)的参数值,当函数调用的时候如果没有指定这个值(传递该参数),编译器会自动用默认值代替。
默认参数从左往右。
- 函数的默认参数从左往右,如果一个参数设置了默认参数,那么这个参数之后的参数都必须设置默认参数。
- 如果函数声明和函数定义分开写,函数声明和函数定义不能同时设置默认参数。
- 推荐函数声明处写默认参数(缺省函数)。因为在分文件的情况下,是声明处的默认参数起效果。
函数的占位参数
函数的参数只有类型名,没有形参名,这个参数就是占位参数。
由于有类型名,所以函数调用的时候必须给占位参数传参。
由于没有形参名,所以函数内部是无法使用占位参数。
void func(int x, int y, int) { cout << "x = " << x << ", y = " << y << endl; return; } func(1, 2, 3); // 必须传参,但是内部不能使用该参数 // 操作符重载的后置++要用这个
三、函数重载(overload)
(多态的体现)
定义
同一个函数名在不同场景下可以具有不同的含义。
意义
方便使用函数名
条件
- 同一作用域
- 参数个数不同
- 参数类型不同
- 参数顺序不同
注意
函数返回值不能作为函数重载的依据
在编写程序的过程中可以忽略他的返回值,所以编译器不将返回值当成依据。
四、C和C++混合编程
// fun.h #ifndef FUNC_H #define FUNC_H #if __cplusplus extern "C" { #endif extern int my_add(int x, int y); extern int my_sub(int x, int y); #if __cplusplus } #endif #endif // FUNC_H // func.c #include <stdio.h> int my_add(int x, int y) { return x + y; } int my_sub(int x, int y) { return x - y; } // main.cc #include <iostream> #include "func.h" using namespace std; int main() { cout << "Hello World!" << endl; cout << my_add(100, 200) << endl; cout << my_sub(100, 200) << endl; return 0; }
IDE
可以自动识别混合的代码,分别使用不同的编译器编译。手动需要先编译C程序再链接两者:
gcc -c func.c -o func.o g++ main.cc func.o -o main
五、类
C 语言 数据是数据 方法是方法 。
出现一个问题 (数据 方法独立 容易造成 方法 调用错误
C 语言 的结构体
在C语言中,行为和属性是分开的,也就是说吃饭这个属性不属于某个类对象,而属于所有共同数据,所以不单单是 PeopleEat
可以调用 Person
数据, AnimalEat
也可以调用 Person
数据,万一调用错误,将会导致问题发生。
由此,属性和方法应该放在一起,一起表示一个具有属性和行为的对象。
封装
- 把变量(属性)和函数(操作)合成一个整体,封装在一个类中;
- 对变量和函数进行访问控制
访问权限
- 在类的内部(作用域范围内),没有访问权限之分,所有成员可以相互访问
- 在类的外部(作用域范围内),访问权限才有意义:
public
,private
,protected
- 在类的外部,只有
public
修饰的成员才能被访问,在没有涉及继承与派生时,private
和protected
是同等级的,外部不允许访问。
访问属性 | 属性 | 对象内部 | 对象外部 |
---|---|---|---|
public | 公有 | 可访问 | 可访问 |
protected | 保护 | 可访问 | 不可访问 |
private | 私有 | 可访问 | 不可访问 |
类的格式
class 类名 { // 抽象的概念 系统不会为其分配空间 private: // 私有 类的外部 不可直接访问 protected: // 保护 类的外部 不可直接访问 public: // 公有 类的外部 可以直接访问 // 在类的内部没有权限之分 都可以相互访问 }
用类去实例化一个对象。
将成员变量设置为 private
- 可赋予客户端访问数据的一致性。如果成员变量不是
public
,客户端唯一能够访问对象的方法就是通过成员函数。如果类中所有的public
权限的成员都是函数,客户在访问类成员时只会默认访问函数,不需要考虑访问成员需不需要添加(),省下不少时间 - 可细微划分访问控制。使用成员函数可使得我们对变量的控制处理更加精细。如果我们让所有成员变量为
public
,每个人都可以读写它。如果我们设置为private
,我们可以实现“不准访问”、“只读访问”、“读写访问”,甚至“只写访问”