C++语言基础四

1、介绍C++所有构造函数

类的对象被创建时,编译系统为对象分配内存空间,并自动调用构造函数,由构造函数完成成员的初始化工作。

即构造函数的作用:初始化对象的数据成员

无参数构造函数:即默认构造函数,如果没有明确写出无参数构造函数,编译器会自动生成默认的无参数构造函数,函数为空,什么也不做,如果不想使用自动生成的无参构造函数,必须要自己显式写出一个无参构造函数。  

一般构造函数:也称重载构造函数,一般构造函数可以有各种参数形式,一个类可以有多个一般构造函数,前提是参数的个数或者类型不同,创建对象时根据传入参数的不同调用不同的构造函数。

拷贝构造函数:拷贝构造函数的函数参数为对象本身的引用,用于根据一个已存在的对象复制出一个新的该类的对象,一般在函数中会将已存在的对象的数据成员值一一复制到新创建的对象中。如果没有显式的写拷贝构造函数,则系统会默认创建一个拷贝构造函数,但当类中有指针成员时,最好不要使用编译器提供的默认拷贝构造函数,最好自己定义并且在函数中执行深拷贝。

类型转换构造函数:根据一个指定类型的对象创建一个本类的对象,也可以算是一般构造函数的一种,这里提出来,是想说有的时候不允许默认转换的的话,要记得将其声明为explict的,来阻止一些隐式转换的发生。

赋值运算符的重载:注意,这个类似拷贝构造函数,将等号右边的本类对象的值复制给等号左边的对象,它不属于构造函数,等号左右两边的对象必需已经被创建。如果没有显式的写赋值运算符的重载,系统也会生成默认的赋值运算符,做一些基本的拷贝工作。

A a1, A a2;
a1 = a2;  // 调用赋值运算符
A a2 = a1; //调用拷贝构造函数,因为进行的是初始化工作,a3并未存在

2、C++的四种强制类型转换

C++的四种强制类型转换:static_cast,dynamic_cast,const_cast,reinterpret_cast

  • static_cast:明确指出转换类型,一般建议将隐式转换都替换成显式转换,因为没有动态类型检查,上行转换(派生类->基类)安全,下行转换(基类->派生类)不安全,所以主要执行非多态的转换操作。
  • dynamic_cast:专门用于派生类之间的转换,type_id必须是类指针,类引用或void*,对于下行转换是安全的,当类型不一致时,转换过来的是空指针,而static_cast,当类型不一致时,转换过来的是错误意义的指针,可能造成非法访问等问题。
  • const_cast:专门用于const属性的转换,去除const性质,或增加cosnt性质,是四种转换符中唯一可以操作常量的转换符。
  • reinterpret_cast:不到万不得已,不要使用这个转换符,高危操作。使用特定:从底层对数据进行重新解释,依赖具体的平台,可移植性差;可以将整型转换为指针,也可以把指针转换成数组;可以在指针和引用之间进行肆无忌惮的转换。

3、指针和引用的区别

指针和引用都是一种内存地址的概念,区别呢,指针是一个实体,引用只是一个别名。

在程序编译的时候,将指针和引用添加到符号表中。

指针它指向一块内存,指针的内容是所指向的内存的地址,在编译的时候,则是将“指针变量名-指针变量的地址”添加到符号表中,所以说,指针包含的内容是可以改变的,允许拷贝和赋值,有const和非const的区别,甚至可以为空,sizeof指针得到的是指针类型的大小。

而对于引用来说,它只是一块内存的别名,在添加到符号表的时候,是将“引用变量名-引用对象的地址”添加到符号表中,符号表已经完成不能改变,所以引用必须而且在定义时被绑定到一块内存上,后续不能更改,也不能为空,也没有const和非const区别。

sizeof引用得到代表对象的大小。而sizeof指针得到的时指针本身的大小。另外在参数传递中,指针需要被解引用后才可以对对象进行操作,而直接对引用进行的修改会直接作用到引用对象上。

作为参数时也不同,传指针的实质是传值,传递的值是地址值;传引用的实质是传地址,传递的是变量的地址。

4、野(wild)指针与悬空(dangling)指针有什么区别?如何避免?

野指针(wild pointer):就是没有被初始化过的指针。

悬空指针(dangling):是指指针最初指向的内存已经被释放了的一种指针。

无论是野指针还是悬空指针,都是指向无效内存区域(这里的无效指的是“不安全不可控”)的指针。访问“不安全可控”(invalid)的内存区域将导致“Undefined Behavior”。

如何避免使用野指针?在平时的编码中,养成在定义指针后且在使用之前完成初始化的习惯或者使用智能指针。

5、说一下const修饰指针如何区分?

下面都是合法的声明,但是含义大不同:

const int * p1; // 指向整型常量的指针,它指向的值不能修改
int * const p2; //指向整型的常量指针,它不能再指向别的变量,但指向(变量)的值可以修改
const int * const p3; //指向整型常量的常量指针。它既不能再指向别的常量,指向的值也不能修改。

理解这些声明的技巧在于,查看关键字const右边来确定什么被声明为常量,如果该关键字右边是类型,则值是常量;如果关键字的右边是指针变量,则指针本身是常量。

6、简单说一下函数指针

从定义和用途两方面来说一下自己的理解:

首先是定义:函数指针是指向函数的指针变量。函数指针本身首先是一个指针变量,该指针变量指向一个具体的函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。

在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上大体是一致的。

其次是用途:调用函数和做函数的参数,比如回调函数。

示例:

char * fun(char * p) {...} // 函数fun
char * (*pf)(char * p) {...} // 函数指针pf
pf = fun; // 函数指针pf指向函数fun
pf(p); // 通过函数指针pf调用函数fun

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值