c++兼容c语言中struct的用法同时将struct升级成了类,用class表示。
c语言结构体中只能定义变量,而c++还可以定义函数。
一、三个成员声明
域分为:局部域、全局域、命名空间域、类域。
在类中,为了方便类的使用和保存,c++用public与private函数分开作用域与访问权限,分配的是类域。
private:
private作用域中通常存储类的成员变量,在private作用域中的成员变量不可以被类外面、主函数、其他类直接访问,只能在当前类内部使用。
由此可以保证安全封装,类里面的数据不会被外界随便修改。
class Person { private: int age;//私有,外面读不了 }public:
public作用域中的成员函数可以直接被访问,主函数,其他类都可以直接调用,并且对外公开接口。
class Person{ public: void setAge(int a); int getAge(); }同时,我们不需要命名太多函数,且函数直接访问结构体,无需传参。
在类里面声明函数,定义函数时要指明类才可以使用类的成员变量。
protected:
该类内部可以直接访问,子类可继承访问,但外部类不可访问。
二、封装
封装的三大特性:封装、继承、多态。
定义:将数据和操作数据的方法进行有机结合,隐蔽对象的属性和实现细节,仅对外公开接口来和对象交互。
封装本质上是一种管理,方便用户使用类。
在同一种多个类中,成员函数会置于公共区,因此只需要一份,且地址相同。
为了方便定义且方便占地址,空类大小为1。
只有成员函数的类也是空类。
三、this指针
this 是成员函数隐含的形参,类型是const*,因此不可被修改。
this 指针存放当前调用函数对象的地址。
*只有非静态成员函数才有this。
this指针可以为空,但是为空时不可调用this指针中的成员。
this指针存放与栈区。
四、类的六个默认成员函数
类有六个默认的成员函数,分别是:构造函数、析构函数、拷贝函数、赋值重载、取地址重载、const取地址重载。
构造函数与析构函数的作用是初始化和清理。
拷贝函数,赋值重载的作用是拷贝复制。
取地址重载、const取地址重载的作用是取地址重载。
初始化和清理:
1.构造函数(类似Init):
构造函数是一个特殊的成员函数,其主要任务不是开辟空间创建对象,而是初始化对象。
其特征如下:
1.函数名与类名相同。
2.无返回值。
3.对象实例化时编译器自动调用对应的构造函数。
4.构造函数可以重载。
编译器生成默认成员函数有什么用?
c++把类型分为内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int,char......自定义类型就是如class,struct,union我们自己定义的类型。
编译器默认生成的构造函数会对自定义类型成员调用它的成员函数。
默认构造函数:
包括:无参构造函数、全缺省构造函数、由编译器默认生成的构造函数。
给缺省值:
内置类型成员可以在类中声明缺省值,而非初始化。默认构造函数会用缺省值进行初始化。
总结:
一般情况下构造函数都需要我们自己编写实现,只有少数情况下可以让编译器自动生成构造函数,类似MyQueque,成员全是自定义类型。
2.析构函数(类似Destroy):
对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
其特征如下:
1.析构函数是在类名前加上字符~。
2.无参数返回值类型。
3.一个类只能有一个析构函数。若为显式定义,系统会自动生成一个默认的析构函数。注意:析构函数不能重载。
4.对象生命周期结束时,c++会自动调用析构函数。
自动生成析构函数:
与构造函数类似:
内置类型不做处理,自定义类型调用它的析构。
拷贝复制:
3.拷贝构造函数:
用同类型的对象拷贝初始化。拷贝构造是构造函数中的一个子分类。其特征如下:
1.拷贝构造函数是构造函数的一个重载形式。
2.拷贝构造的参数只有一个且必须是同类类型对象的引用,如果直接传值编译器会报错,因为会引发无限递归调用。
3.若未显示定义,编译器会生成默认的拷贝构造函数。默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫浅拷贝,或者值拷贝。在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。
为什么拷贝构造函数参数一定要用引用传参?
因为传值会导致传参时进行无限递归调用,必须传引用。
两种等价写法:
Class d1(d2); Class d1 = d2;浅拷贝与深拷贝:
由于浅拷贝只进行值的复制,所以很多情况下使用浅拷贝会出现错误,所以需要自行编写拷贝构造进行深拷贝。
总结:
1.如果没有管理资源,一般情况下不需要写拷贝构造,使用默认拷贝构造就可以。
2.如果成员都是自定义类型或内置类型没有指向资源,也类似。
3.如果不需要析构,通常都可以不写构造。
4.如果内部有指针或者一些值指向资源,就需要编写拷贝构造进行深拷贝。