C++ 笔记3 | 显示类型转换 类 对象 类的定义和实例化

本文介绍了C++中的引用,包括定义、常引用及其与指针的区别。接着讲解了类型转换,包括隐式和显示转换,并提供了不同类型的显示转换操作符。此外,还涉及到了类和对象的基础知识,如对象的属性和行为,以及类的定义和实例化。文章强调了慎用宏和避免不必要的类型转换。
摘要由CSDN通过智能技术生成

十 、C++引用(Reference)

1 定义

1)引用即别名,引用就是某个变量别名,对引用操作和对变量本身完全相同.
2)语法
类型 & 引用名 = 变量名;
注:引用必须在定义同时初始化,而且在初始化以后所绑定的目标变量不能再做修改.
注:引用类型和绑定目标变量类型要一致。

2 常引用

1)定义引用时可以加const修饰,即为常引用,不能通过常引用修改目标变量.
const 类型 & 引用名 = 变量名;
类型 const & 引用名 = 变量名;//和上面等价

2)普通引用也可以称为左值引用,只能引用左值;而常引用也可以称为万能引用,既可以引用左值也可以引用右值。

3)关于左值和右值
左值(lvalue):可以放在赋值表达式左侧,可以被修改
右值(rvalue):只能放在赋值表达式右侧,不能被修改

练习:测试下面表达式结果,是左值还是右值?
int a,b;
a+b;//右值
a+=b;//左值
++a;//左值
a++;//右值

3 引用型函数参数

1)可以将引用用于函数的参数,这时形参就是实参别名,可以通过形参直接修改实参的值;同时还能避免函数调用时传参的开销,提高代码执行效率。
2)引用型参数有可能意外修改实参的值,如果不希望修改实参,可以将形参声明为常引用,提高效率的同时还可以接收常量型的实参。

4 引用型函数返回值

1)可以将函数的返回类型声明为引用,这时函数的返回结果就是return后面数据的别名,可以避免返回值带来的开销,提高代码执行效率.
2)如果函数返回类型是左值引用,那么函数调用表达式结果就也将是一个左值。
注:不要从函数中返回局部变量的引用,因为所引用的内存会在函数返回以后被释放,使用非常危险!可以在函数中返回成员变量、静态变量、全局变量的引用。

int& func(void){
	...
	return num;
}
func() = 100;//ok

5 引用和指针

1)如果从C语言角度看待引用的本质,可以认为引用就是通过指针实现的,但是在C++开发中,推荐使用引用,而不推荐使用指针.
int i = 100;
int* const pi = &i;
int& ri = i;
*pi <=等价=> ri
2)指针可以不做初始化,其目标可以在初始化以后随意改变(指针常量除外),而引用必须做初始化,而且一旦初始化所引用的目标不能再改变.
int a=10,b=20;
int* p;//ok
p = &a;
p = &b;
--------------------
int& r;//error
int& r = a;
r = b;//ok,但不是修改引用目标,仅是赋值运算

//下面内容了解
3)可以定义指针的指针(二级指针),但是不能定义引用的指针.
int a = 10;
int* p = &a;
int** pp = &p;//二级指针
------------------------
int& r = a;
int&* pr = &r;//error,引用的指针
int* pr = &r;//ok,仅是普通指针

4)可以指针的引用(指针变量别名),但是不能定义引用的引用。
int a = 100;
int* p = &a;
int* & rp = p;//ok,指针的引用
-----------------------------
int& r = a;
int& & rr = r;//error,引用用的引用
int& rr = r;//ok,但是仅是一个普通引用

5)可以指针数组,但是不能定义引用数组
int i=10,j=20,k=30;
int* parr[3] = {&i,&j,&k};//ok,指针数组
int& rarr[3] = {i,j,k};//error

6)可以定义数组引用(数组别名)
int i=10,j=20,k=30;
int arr[3] = {i,j,k};
int (&rarr)[3] = arr;//ok, 数组引用

7)和函数指针类似,也可以定义函数引用(函数别名)
void func(int i){}
int main(void){
void (*pf)(int) = func;//函数指针
void (&rf)(int) = func;//函数引用
pf(100);
rf(100);
}

十一、 类型转换

1 隐式类型转换

char c = ‘A’;
int i = c;//隐式
-----------------
void func(int i){}
func©;//隐式
-----------------
int func(void){
char c=‘A’;
return c;//隐式
}

2 显示类型转换

2.1 C++兼容C中强制类型转换
char c = ‘A’;
int i = (int)c;//C风格
int i = int©;//C++风格

2.2 C++扩展了四种操作符形式显式转换
1)静态类型转换:static_cast
语法:
目标变量 = static_cast<目标类型>(源类型变量);
适用场景:
主要用于将void*转化为其它类型的指针
举例:static_cast.cpp

#include <iostream>
using namespace std;

int main(void){
   
    int* pi = NULL;
    //char c = (long)pi;//C风格强转
    char c = long(pi);//C++风格强转

    //静态类型转换
    void* pv = pi;
    pi = static_cast<int*>(pv);//合理
    return 0;
}

2)动态类型转换:dynamic_cast//后面讲
语法:
目标变量 = dynamic_cast<目标类型>(源类型变量);

3)去常类型转换:const_cast
语法:
目标变量 = const_cast<目标类型>(源类型变量);
适用场景:
主要用于去掉指针或引用const属性.
举例:const_cast.cpp

#include <iostream>
using namespace std;
int main(void){
   
    //volatile是标准C语言的关键字
    //被volatile修饰的变量表示易变的,告诉编译
    //器每次使用该变量时,都要小心从内存中读取,
    //而不是取寄存器的副本,防止编译器优化引发
    //的错误结果.
    volatile const int i = 100;
    int* pi = const_cast<int*>(&i);
    *pi = 200;
    cout << "i=" << i << ",*pi=" << *pi
        << endl;//200,200
    cout << "&i=" << (void*)&i << ",pi=" << 
         pi << endl;

    return 0;
}

4)重解释类型转换:reinterpret_cast
语法:
目标变量=reinterpret_cast<目标类型>(源类型变量);
适用场景:
在指针和整型数进行显式转换.
任意类型指针或引用之间显式转换.

eg:已知物理内存地址0x12345678,向该地址存放一个整型数100?
int* paddr = reinterpret_cast<int*>(0x12345678);
*paddr = 100;

代码:reinterpret_cast.cpp

#include <iostream>
using namespace std;
int main(void){
   
    //"\000"-->'\0'
    char buf[] = "0001\00012345678\000123456";
    struct HTTP{
   
        char type[5];
        char id[9];
        char passwd[7];
    };
    HTTP* pt = reinterpret_cast<HTTP*>(buf);
    cout << pt->type << endl;//0001
    cout << pt->id << endl;//12345678
    cout << pt->passwd << endl;//123456

    return 0;
}

小结:
1 慎用宏,可以使用const、enum、inline替换
#define PAI 3.14
–》const double PAI = 3.14;

#define SLEEP 0
#define RUN 1
#define STOP 2
–》enum STATE{SLEEP,RUN,STOP};

#define Max(a,b) ((a)>(b)?(a):(b))
–》inline int Max(int a,int b){
return a > b ? a : b;
}

2 变量随用随声明同时初始化
3 尽量使用new/delete替换malloc/free
4 少用void*,指针计算,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值