2024/01/09

回顾c++

目录

1. 指针常量和常量指针:

c++判断数据类型

2. 引用:

2.1 引用做函数参数

2.2 引用做函数返回值

2.3 引用做函数返回值,函数的调用可以作为左值

2.4 引用的本质

2.5 常量引用

3. 函数重载:

3.1 要求:

3.2 注意事项:

3.2.1 引用作为函数重载条件:

3.2.2 函数重载碰到默认参数

4. 静态成员

4.1 静态成员变量

4.1.1 特点:

4.1.2 静态成员变量两种访问方式:

4.1.3 静态成员变量访问权限

4.2 静态成员函数

4.2.1 特点:


1. 指针常量和常量指针:

c++判断数据类型

#include <typeinfo>
int main(){
    int*p1,p2;
    cout<<typeid(p1).name()<<endl;
    cout<<typeid(p2).name()<<endl;
}

输出:Pi,i

说明p1是一个指针,p2是int

指针常量:int* const,指针的指向是不可以修改的,但值可以修改

常量指针:const int*,指向可以修改,但指向的值不可以修改

#include <iostream>

using namespace std;

int main(int argc, char const *argv[])
{
    /* code */
    int a = 10;
    int b = 1;

    int* p = &a;

    int* const p2 = &a;		//不能改变指向,p2 = &b报错

    const int* p3 = &a;		//不能改变指向的值,*p3 = b报错
    //int const* p3 =  &a;	//效果一样

    const int* const p4 = &a;	//既不能也不能

    return 0;
}

所以重点在于const的右侧是什么,如果右侧有*,则说明不能修改值;否则,不能修改指向。

2. 引用:

int &a = b;

a是b的引用,给变量b取别名。a与b完全等价,操作a相当于操作b,a和b的地址相同。

引用必须初始化,且初始化后不可以再改变:

int a = 10;
int &b = a;	//必须初始化

int c = 20;
b = c;	//代码不报错,但是相当于赋值,而不是更改引用

cout<<a<<endl;	//20
cout<<b<<endl;	//20
cout<<c<<endl;	//20

2.1 引用做函数参数

作用:简化指针

//交换函数

//1.值传递:形参不会修饰实参(a和b最后不会改变)
void swap1(int a, int b)
{
	int c = a;
	a = b;
	b = c;
}

//2.地址传递:a和b最后改变
void swap2(int* a, int* b)
{
	int c = *a;
	*a = *b;
	*b = c;
}

//3. 引用传递:
void swap3(int& a, int& b)
{
	int c = a;
	a = b;
	b = c;
}

int main()
{
	int a = 10;
	int b = 20;
	swap3(a, b);	//a = 20, b = 10
}
void func(int& ref)
{
	ref = 100;	//因为ref是引用,转换为*ref = 100
}

int main()
{
	int a = 10;
	int& ref = a;	//给a起别名叫ref,相当于int* const ref = &a
	func(a);
	
	cout<<a<<" "<<ref<<endl;	//100 100
}

2.2 引用做函数返回值

注意,不要返回局部变量的引用

int& test1()
{
	int a = 10;	//局部变量,存在于栈区
	return a;
}
int main()
{
	int &ref = test1();
	cout<<ref<<endl;	//a的内存已经被释放,所以会报错
}

改正:

int& test2()
{
	static int a = 10;	//静态变量,存在于全局区
	return a;
}
int main()
{
	int &ref = test2();
	cout<<ref<<endl;	//不会报错
}

2.3 引用做函数返回值,函数的调用可以作为左值

int& test2()
{
	static int a = 10;	//静态变量,存在于全局区
	return a;
}
int main()
{
	int& ref =  test2();
	cout<<ref<<endl;	//10
	test2() = 1000;
	cout<<ref<<endl;	//1000
}

2.4 引用的本质

指针常量(指针的指向不可以改,指向的值可以改)

int& ref === int* const ref

int& ref = a;
int* const ref = &a;
int main()
{
	int a = 10;
	int& ref = a;	//给a起别名叫ref,相当于int* const ref = &a
	ref = 20;
	
	cout<<a<<" "<<ref<<endl;	//20 20
}

但是ref必须一直指向a。

2.5 常量引用

修饰形参,防止误操作:用const修饰,防止形参修改实参

int & ref = 10;		//报错,必须引用一块合法的内存空间

const int& ref = 10;	//不报错,
//加上const之后,编译器将代码修改为int temp = 10; int& ref = temp

但是常量引用只读,不可修改:

const int& ref = 10;
ref = 20;			//报错,const之后变为只读,不可修改

下方的操作会导致形参修改实参:

void showValue(int& ref)
{
	ref = 1000;
	cout<<ref<<endl;	//1000
}

int main()
{
	int a = 100;
	showValue(a);
	cout<<a<<endl;	//1000
}

改正方法:

void showValue(const int& ref)
{
	//ref = 1000;	//如果写这行会报错
	cout<<ref<<endl;	//100
}

int main()
{
	int a = 100;
	showValue(a);
	cout<<a<<endl;	//100
}

3. 函数重载:

相同名称的函数可以进行复用。

3.1 要求:

必须在同一个作用域,函数的参数个数/类型/顺序不同(注意与函数返回值无关)

void func()
{
	cout<<"func"<<endl;
}

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

int main()
{
	func();	//输出:func
	func(2);	//输出:myfunc
}

3.2 注意事项:

3.2.1 引用作为函数重载条件:
void func(int& a)			//int& a = 10不合法
{
	cout<<"func1"<<endl;
}

void func(const int& a)		//const int& a = 10合法
{
	cout<<"func2"<<endl; 
}

//类型不同,可以重载 
int main()
{
	int a = 10;
	func(a);		//调用没有const的
	func(10);		//调用const的
}

因为我们从上面知道,const int& a是一个常量引用,常量引用只读,不可修改。所以如果传入的参数是10(一个常量),则func2会被输出。

3.2.2 函数重载碰到默认参数
void func(int a)
{
	cout<<"func"<<endl;
}

void func(int a, int b = 10)
{
	cout<<"func2"<<endl;
}

int main()
{
	func(10);		//报错,因为两个函数都可以被调用
	func(10,20);	//运行func2
}

4. 静态成员

在成员变量和成员函数前加static关键字

4.1 静态成员变量

4.1.1 特点:

所有对象共享同一份数据

在编译阶段分配内存(全局区)

类内声明,类外初始化(必须初始化,否则报错)

class Person
{
public:
    static int m_A;
}

//类外初始化
int Person::m_A = 100;

int main()
{
    Person p;
	cout<<p.m_A<<endl;		//100
	
	Person p2;
	p2.m_A = 200;
	
	cout<<p.m_A<<endl;		//200
    
}
4.1.2 静态成员变量两种访问方式:

通过对象访问:p.m_A

通过类名访问:Person::m_A

int main()
{
	//通过类名访问
	cout<<Person::m_A<<endl;
	
	//通过对象访问
	Person p;
	cout<<p.m_A<<endl;
}
4.1.3 静态成员变量访问权限

静态成员变量也是有访问权限的,如果是私有静态成员变量,同样不能直接类外访问

class Person
{
private:
	
	//所有对象共享同一份
	static int m_A;
};

int Person::m_A = 10;

int main()
{
	//通过类名访问
	cout<<Person::m_A<<endl;	//报错inaccesible
}

4.2 静态成员函数

4.2.1 特点:
  • 所有对象共享同一个函数

  • 只能访问静态成员变量

  • 也有两种访问方式:可以通过对象或者通过类名访问

  • 静态成员函数也有访问权限(类外访问不到private的成员函数)

class Person
{
public:
	static void func()
	{
		m_A = 100;
		//m_B = 200;		//报错,静态成员函数只能访问静态成员变量
		cout<<"static void func"<<endl;
	}
	
	static int m_A;
	int m_B;	//非静态成员变量
	
	//静态成员函数也有访问权限
private:
	static void func2()
	{
		cout<<"func2"<<endl;
	}
};

int Person::m_A = 0;

int main()
{
	//通过对象访问
	Person p;
	p.func();
	
	//通过类名访问
	Person::func();
	
	Person::func2();	//报错,静态成员函数不能类外调用
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值