1.引用与指针的相同与不同:
相同:底层逻辑相同,在汇编那层引用和指针是一致的,换句话说,引用就是被装饰后的指针,虽然外表有所差异,但内在是相同的。
不同:
1.定义的时候,引用必须要初始化,指针可以不初始化。
2.引用在初始化时引用一个对象,此后不能修改,指针指向的对象可以修改。
3.引用的对象不能是NULL,指针可以指向NULL。
4.用sizeof的时候,引用是返回引用类型的大小,指针是返回指针的大小(32位下4个字节,64位下8个字节)。
5.访问实体的方式不同,指针需要解引用,引用是通过编译器自己处理。
6.没有多级引用,有多级指针。
7.引用自增是引用的对象的值自增,指针自增是指针所指的地址自增。
8.引用使用起来更加安全。
9.引用是对对象起一个别名,指针是指向的对象的地址。
2.内联函数(inline)
宏可以用于写一些简单的函数,比如交换两个数的值。但用宏写函数时,由于宏的特性,常会引起一些错误,比如漏加括号导致计算结果和预想的不同。内联函数就是为了解决宏的这些缺点而产生的。
内联函数的关键字是inline,放在函数返回类型的前面,如下所示,add函数是一个内联函数。
inline int add(int a, int b)
{
return a + b;
}
内联函数和宏一样,在预编译阶段展开(即预编译阶段会把所有调用该函数的地方用函数的内容替换),因此说内联函数拥有宏的特点,但同时它的写法又酷似函数,因此也同样有函数的特点。
内联函数的特点:
1.和宏一样在预编译阶段展开,没有栈的开辟与销毁,是一种以空间换时间的做法。
2.内联函数是向编译器建议和宏一样展开,但如果内联函数内的代码很长,编译器仍会以函数的方式对待(即在运行阶段开辟、销毁函数栈帧)。
3.内联函数的定义和声明必须放在一块,不能出现声明放头文件,定义放.cpp的文件中,因为内联函数是像宏一样展开,而不是像函数一样跳转到函数所在的地址,所以头文件链接不到。
3.NULL的变化
在c语言中,NULL的类型是(void*)0,但在C++中NULL就是数字0,因此C++引用nullptr(全小写)来代替NULL给指针赋值。
4。初始类和对象
所谓类和对象,就是关注具体的事物,而不关心事物的特征和其动作。在C++中,像struct定义的结构体也成为了类的一种。但和c语言不同的一点是在C++中可以在struct中定义函数。
类的定义:
常用关键词class,也可以用struct,(两者的区别放在下面揭晓)如下图定义了一个名叫home的类,类中有成员变量child、child_num,有成员函数ge_cnum。
class home
{
public:
void get_cnum()
{
return child_num;
}
private:
char child[20];
int child_num;
};
常见的类的定义方式有两种,一种是类的成员函数和成员变量一块定义,一种是类的成员变量和成员函数的声明放在.h文件中,类的成员函数的定义放在.cpp文件中。需注意,若成员函数在类内定义,则编译器可能会认为其是内联函数。
当类的成员函数和成员变量分开定义的时候,成员函数的写法需要在返回类型和函数名之间加上
“类名::”,如下图所示:
在用成员函数的时候,有时候可能会面临函数的形参名和类的成员变量名相同的情况,在这时函数内调用该名字是调用谁?
答案是两个val都会代表形参名,因此设计类内函数的时候,请务必注意形参名和类的成员变量名是否相同,一般都会在成员变量名前或后加一个“_”来区分。但若真想把成员变量名和形参名设计的一样,又想要调用形参,该怎么办?
class node
{
void get_val(int val)
{
this->val = val;
}
int val;
};
答案是用this指针,此时this->val就是成员变量了,而没有this指针指向的val仍是形参。
类的访问权限:
类的访问权限有public、protected、private三种,此处先认为protected和private相同(因为两种的区别是在继承阶段,现在还没有写到继承),此处主要分析public和private的不同。
类的权限的管理范围是从该权限出现的那行开始,到下一个权限出现的地方或到类的结束。也就是说,在一个类中可能存在多个权限。
类的权限管理的是类内的一切,包括类内的成员函数和成员变量。
public的权限简单来说就是在类外也可以通过对象名.函数名的方式去使用,但是private下的在类外都不能使用。既然private下的无法在类外使用,那就只能在类内使用了,所谓在类内使用,就是用类内的成员函数来调用该成员变量。这样做的好处是无法随意修改类的成员变量和成员函数,更加的安全。
class和struct的区别便是不写权限时,class默认成员都是private,struct默认都是public,但只要写了权限两者就没有区别了。
类的作用域:
一个类就是一个新的作用域,类的所有成员都在此作用域中,这也说明了为什么在类外写函数定义需要加上作用域。(可以类比命名空间)
类的使用:和c语言的struct定义的结构体调用方式基本一致,但有时候可能会有所不同,不同之处下面再讲。
类的定义和声明:
声明只是说明类内有什么,但不会开辟实际的空间,只有类的定义才会开辟实际空间(就好比类的声明是一个计划书,类的定义是对计划的实施)。因此不能在声明了类以后就使用类.成员名去调用成员,而是创建实际的对象后用对象去调用成员。
类的大小:
类的大小和结构体的大小算法一致,也遵循字节对齐原则,同时,类的成员函数不算在类的大小中,因为类的成员函数实际是放在公共代码区而不是类内(这一点下面会考到!),和全局函数类似。然而,如果类中没有一个成员或者只有成员函数的时候,类的大小是多少?这取决于编译器,一般大小是1,但不管是什么编译器,类的大小都不会是0,因为至少需要有一个字节的大小去区分同一个类下的不同变量。类这种区分的方式叫占位,其作用是表示对象的区别。所开辟得到空间不是为了存储数据,而是为了说明有这个对象的存在。
this指针:
在C++中,this指针指向对象,用于存放对象的地址。this指针可以显示调用(即在成员函数中使用),但不能出现在形参中,因为编译器会默认调用this指针作为形参。也就是说,实际形参的个数比自己写的要多一个(this指针),在调用时实参的个数也比写的多一个(取对象的地址)。
5.C和C++的区别之一:
数据和方法是否分离(封装),在C中是分离的,C++中是封装在一起的,封装在一起可以杜绝随机访问,这也是C++的优势所在。
6.默认成员函数:
所谓默认成员函数,就是你不写编译器会自己写一个的函数,本篇中主要讲两个:默认构造函数和默认析构函数。
构造函数:
在对象创建的时候自动调用,用于对象的初始化。
特征:
1.构造函数名和类名必须一致。
2.构造函数无返回类型,即直接不写返回类型(这里要和void类型区分开)。
3.构造函数会在对象创建后自动调用。
4.构造函数可以有形参,因此可以构成函数重载。
5.当形参为空或全缺省时,对象的定义不能是 “类名 对象名()”,而应该是“类名 对象名”。因为前者编译器无法和函数声明进行区分。
默认构造函数:
默认构造函数有三种:无参构造函数、全缺省默认构造函数、不写构造函数时编译器自己写的构造函数。其特点是对象定义的时候不用加括号。
对于编译器自己写的构造函数,内置数据类型不会进行处理(如int、char、double、所以指针类型等),自定义类型会调用其默认构造函数。由于内置类型不会进行处理,所以允许在声明时给缺省值。如下图val在声明中赋值1,data在声明中被赋值2,data又在构造函数中被重新赋值,因此此时data=3,val=1.
析构函数:
在对象销毁的时候调用,一般用于对成员的销毁。(如malloc、fopen等)。
析构函数的写法是~类名(),无返回类型,无形参。同时析构函数由于没有形参,因此没有函数重载。
析构函数和构造函数类似,不写的时候编译器会调用默认析构函数。(特点和默认构造函数类似)。
本篇讲了引用和指针的区别、内敛函数、NULL与nullptr、类和对象、构造函数、析构函数,粗略说明了c和C++的区别(封装)。