(黑马C++)L02 类 内联函数 函数重载

设计类的代码框架

class 类名{
public: //公共权限
    设置 成员属性
    设置 成员函数
}

//使用类 创建对象 -> 实例化对象
类名 对象名

//通过对象来设置调用成员函数

 类和对象的关系

类是对对象的抽象,对象是对类的实例。

案例一

设计一个圆的类,可以计算圆的周长

#include <string>
#include <iostream>
using namespace std;

const double pi = 3.14;
//设计一个类 求圆的周长
class Circle {//class代表生成一个类
public:
	//成员属性
	int r;
	//成员函数
	double calculateZC() {
		return 2 * pi * r;
	}
};

void  test01() {
	Circle c1; //创建一个圆的对象
	c1.r = 2;  //对成员属性赋值
	cout << "圆c1的周长为:" << c1.calculateZC() << endl;
}

int main()
{
	test01();
	system("pause");
	return 0;
}

案例二

设计一个学生类,每个学生有姓名学号,可以对学生的信息进行输出

#include <string>
#include <iostream>
using namespace std;

class Student {
public:
	//成员变量
	string name;
	long long studentId;

	//使用成员函数修改成员变量
	void setName(string s) {
		name = s;
	}

	void setId(long long id) {
		studentId = id;
	}

	//使用成员函数打印信息
	void show() {
		cout << "该学生的姓名为:" << name << endl;
		cout << "该学生的学号为:" << studentId << endl;
	}
};

void test02() {
	//创建一个学生
	Student s1; //实例化
	s1.setName("冯世龙");
	s1.setId(3220221637);
	s1.show();
}

int main()
{
	test02();
	system("pause");
	return 0;
}

 内联函数

1)内联函数的引出

在C语言中经常把一些短并且执行频繁的计算写成宏,来避免函数调用的开销,宏函数举例:

#include <iostream>
using namespace std;

#define MyAdd(x, y) x+y;

void test() {
    int ans = MyAdd(2, 3);
    cout << "ans = " << ans << endl;
}

int main() {
    test();
    return 0;
}

在C++出现后,使用预处理宏会出现两个问题:

1.宏看起来像函数调用,但没有参数类型及返回值,实际会有隐藏的难以发现的问题,例如执行ans = MyAdd(2, 3)*2时会返回2+3*2;

2.宏函数没有作用域;

3.由于C++中预处理器不允许访问类的成员,所以预处理宏不能作类的成员函数。

为了继承宏的效率,没有函数调用的开销,又可以像普通函数那样可以进行参数、返回值的安全检查,又可以作为成员函数,C++引入了内联函数。

2)内联函数的基本概念

内联函数本身也是一个真正的函数,具有普通函数的所有行为,唯一不同之处在于内联函数会在适当地方像预定义宏一样展开,所以不需要函数调用的开销。

在普通函数前加上inline关键字,使其成为内联函数,但是必须将函数声明和函数体结合在一起。

内联函数避免了函数调用时的压栈、跳转、返回的开销,是用空间换时间。

3)类内部的内联函数

编译器会默认为类内部的成员函数加上inline关键字,定义为内联函数。

4)内联函数和编译器

C++中内联编译会有一些限制,以下情况编译器可能考虑不会将函数进行内联编译。

1.存在循环语句;

2.存在过多的条件判断语句;

3.函数体过于庞大;

4.对函数进行取址操作。

内联仅仅是给编译器的一个建议,但编译器不一定会接受这种建议,一个好的编译器会将小的、简单的函数自动设置为内联函数。

函数的默认参数及占位参数

C语言中没有默认参数和占位参数。

1)默认参数

C++在声明函数时可以为一个或多个参数指定默认参数值,在函数调用时如果没有传入参数,编译器会自动用默认值代替。

void test(int a = 10, int b = 20) { //直接在参数后面加上默认值
    cout << "a + b = " << a+b << endl;
}

如果有一个位置有了默认参数,那么从这个位置开始,从左往右都要有默认参数。

2)函数的占位参数

void test2(int a, int) { //占位参数
    
}

如果有了占位参数,函数调用时必须要提供这个参数,但是用不到,函数体里面没有这个名,只有在重载++符号时会用到。

如果函数声明里面有了默认参数,函数实现里面必须没有。

函数重载

能使名字更方便使用,在C语言中,函数名必须是唯一的,在C++中允许出现同名的函数(必须在同一个作用域),但函数的参数个数或参数类型或参数顺序不同,这种现象成为函数重载。

1)函数重载的基本语法

无法按照返回值的类型不同对两个同名函数进行重载。

当函数重载遇到了默认参数,要注意避免二义性的问题。

引用的重载版本此时会调用(const int &a)。

void func(int &a) {
    cout << "int &a" << endl;
}

void func(const int &a) {
    cout << "const int &a" << endl;
}

void test(){
    func(10);
}

2)函数重载的实现原理

在函数重载时,编译器内部会用不同的参数类型来修饰不同的函数名,用于内部自己区分。

extern "C" 浅析

C++中如果要调用C语言的方法,要加上 extern "C" 方法名,说明该方法按照C语言做链接。

C语言和C++语言封装的区别

C语言struct的成员函数要在结构体外进行定义,属性和行为分开处理了,类型检测不够。

C++语言的struct成员函数在结构体内进行定义,属性和行为绑定在一起,严格类型转换检测。

C++中struct和class是一个意思,唯一的不同是默认权限,struct默认权限是public。

成员属性设为私有

C++中class如果不声明权限,会默认权限是private,私有权限只能在类内部访问,类外部不可以访问;公共权限在类的内部和外部都可以访问;保护权限在类的内部和子类可以访问。

建议将成员函数都设为私有,自己提供公共的对外接口set或者get方法来进行访问。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值