目录
引用:
什么是引用?
给变量起别名,操作这个引用相当于操作这个变量
注意事项:必须初始化,只能绑定一个变量,const 对const
什么时候传地址,什么时候传值?
当修改实参变量时,传实参变量的地址;(传实参变量的地址,既可以使用也可以修改实参变量的值)
当只使用不修改实参变量值时,传实参变量名;(传实参变量名,只能使用实参变量的值)
哪些地方可以使用引用?
引用可以做形参(解决了传值和传地址的问题),可以做返回值(函数调用可以做左值)
引用是否占用内存空间?
引用使用时不占内存空间,编译器给引用分配空间 是 编译器优化:不将这个空间展示给开发人员,不能操作这段空间 新的数据类型
指针和引用的区别?
左值引用,右值引用
左值:可赋值可取地址
右值:反之;左值引用只能绑定左值,右值引用只能绑定右值,引用不能为空,指针可以
如何将左值转为右值?
std::move()
右值引用的作用以及什么时候使用?
对象移动,解决对象拷贝的开销问题
左值引用作用,右值引用?
引用可以充当函数的形参和返回值,左值引用就是返回的只能是左值,接收的只能是左值;右值也相同
代码举例:
#include <iostream>
using namespace std;
void swap(int &a, int &b) //引用作为函数形参
{
int temp = 0;
a = temp;
temp = b;
b = a;
}
int & func2(const int &a) //常引用,只能使用 不能修改其绑定的值
{
static int num = 5;
num++;
cout << num << endl;
return num;
}
int & getNum( int a)
{
int temp = a + 1;
return temp;
}
int func3(const int a)
{
int num = 5;
return num;
}
int func(const int a)
{
int num = 5;
return num;
}
struct node
{
int num;
int &r_num;
};
int main()
{
//char * ptr = "hello world!";
//func(ptr);
//cout << ptr <<endl;
int a = 5;
int b = 6;
swap(a,b);
cout << a << "" << b << endl; //完成 a b 交换
getNum(a) = 6 //警告,但可以使用,给return 赋值 函数调用做返回值,修改返回的值
// int count = 5;
// int &r_count = count;
// r_count++;
// cout << count << endl;
// int num = 6;
// int &r_count = num;
// const int num = 6;
// const int &r_num = num; //常引用
//r_num++;
// int num = 5;
// int &r_num = num;
// cout << sizeof(r_num) << endl;
// cout << sizeof(struct node) << endl;
return 0;
}
C++内联函数:
时间换空间,空间换时间
时间:运行时间,编译时间
空间:内存空间
使用编译时间换内存空间(宏函数)
使用内存空间换运算时间(inline(只能修饰函数C99)内联函数:将函数体的代码段内嵌到函数调用的地方)
inline:将代码段内嵌到函数调用的地方,省去了调用返回的过程,提高了程序的运行效率
C++对inline:C语言只要申明为inline,一定会以内嵌的方式进行处理;
请求编译器为该函数内联!(判断,循环,静态,递归,异常处理)
什么时候使用inline?
功能简单且代码短小(5行左右),频繁调用;使用注意事项:调用内联函数之前必须申明或定义该函数
在申明内联函数时,关键字inline必须和函数定义结合在一起,否则编译器会直接忽略内联请求
#include <iostream>
using namespace std;
namespace inlineFunc
{
#define MAX(a, b) ((a) > (b)) ? (a) : (b) //傻瓜式替换:预处理阶段(没有空间分配过程)
inline int max_num(int a, int b);
void func()
{
max_num(5, 6);
}
inline int max_num(int a, int b) //自定义函数
{
return a > b ? a : b;
}
//自定义函数
//处理阶段:编译时检查语法,运行时函数机械能栈进栈出
//处理过程: 通过函数名称找到函数的入口地址,给形参分配空间,传值;执行函数体的语句,函数返回,释放空间
} // namespace inlineFunc
int main()
{
inlineFunc::max_num(5, 3);
inlineFunc::max_num(5, 3);
}
C++函数升级:
函数默认参数:函数定义时给形参指定值
默认参数规则:当前参数的右边参数必须有默认参数;
函数占位参数:预留参数接口,函数调用时必须指定参数;
函数重载:函数名可以相同,但是函数形参不同;(形参个数类型不同)
函数重载的条件:
1.形参个数相同,但是类型不同;
2.形参个数不同;
3.形参个数相同,类型不同,顺序不同;
4.重载的注意事项:注意默认参数对重载条件的影响
思考:函数重载实现原理?
namespace OverLoader
{
int add(int a, int b) //add_int_int
{
cout << "add(int, int)" << endl;
return a + b;
}
int add(char a, char b) //add_char_char
{
cout << "add(char, char)" << endl;
return a + b;
}
int add(int a)
{
cout << "add(int)" << endl;
}
int add(char a, int b)
{
}
int add(int a, char b)
{
}
int sub(int a = 5, int b = 5, int c = 5)
{
return a - b - c;
}
int mul(int a, int b, int) //
{
return a * b;
}
void func()
{
cout << add(6,5) << endl; //add_int_int(5,6)
cout << add('a','b') << endl; //add_char_char(5,6)
cout << add(6) << endl;
cout << sub(6,5,1) << endl;
cout << sub() << endl;
cout << mul(4,5,0) << endl;
int (*p_add)(int,int) = add;
cout << "p_add = " << p_add(6,5) << endl;
}
}
int main()
{
OverLoader::func();
return 0;
}
结构体:
C中的结构体:
#include <stdio.h>
struct node
{
int num;
// void test()
// {
// printf("hello world!\n");
// }
void (*p_func)();
};
void test()
{
printf("hello world!\n");
}
int main()
{
struct node p;
p.num = 1;
p.p_func = test;//输出hello world
return 0;
}
c++对struct的升级:
1、定义变量(机构体名+变量名)
2、结构体可以保存函数
3、结构体可以继承
4、结构体可以多态
5、结构体可以封装(权限修饰符:public private protected)
结构体默认访问权限public
private、protect不能结构体外访问,只能在内部函数中访问
public既可以结构体内访问,也可以在结构体外访问
c++新的数据类型class
class vs struct:
class默认权限是private,struct默认权限是public,写的时候要加public
叫法区别:
class类 struct结构体 class定义的变量称之为对象,struct称之为变量,class里的保存的变量称之为属性或者成员变量,保存的函数称之为方法。
#include <iostream>
using namespace std;
class Node
{
private: //不能结构体外部访问,可以在内部函数中访问
int num;
public: //即可以结构体内部访问,也可以在结构体外部访问
virtual void test()
{
cout << "func test" << endl;
cout << num << endl;
}
};
class Nodes : public Node
{
public:
virtual void test()
{
cout << "func test nodes!" << endl;
}
};
class Student
{
public:
int mNum;
char mName[20];
int mage;
// void eat() //类内实现:有可能被内联;
// {
// cout << "eat" << endl;
// }
void eat();
};
void Student::eat()
{
cout << "eat" << endl;
}
int main()
{
//struct Node p;
// Node p;
// p.test();
// //p.num = 3;
// Nodes ps;
// ps.test();
// Node *pp = new Nodes;
// pp->test();
Student s;
s.eat();
return 0;
}
代码规范:建一个.h,一个.cpp,一个main.cpp
举例:
student.cpp
#include "Student.h"
void Student::eat()
{
cout << "eat" << endl;
}
student.h
#pragma once
#include <iostream>
using namespace std;
class Student
{
public:
int mNum;
char mName[20];
int mage;
// void eat() //类内实现:有可能被内联;
// {
// cout << "eat" << endl;
// }
void eat();
};
main.cpp
#include <iostream>
#include "Student.h"
using namespace std;
int main()
{
Student s;
s.mNum = 10;
s.eat();
return 0;
}