Day06 C++类重点梳理

其实这也不算是day06吧,梳理了好几天,算是总结为一个专题,作为C++类的重点要点,主要参考资料是《C++新经典》!

基础知识点

认识类

类是自定义的数据类型,包括成员(属性)与方法(行为);

类内成员与方法具有访问权限,默认private,另有public和protected可供设置;

文件防卫

使用一组预编译命令,防止重复编译

#ifndef __XXXXX__

#define __XXXX__

.....

#endif

访问权限

Public:没有限制;

Protected:类内成员函数中,子类成员函数中,类友元函数;

Private:类内成员函数中,类友元函数;

 构造函数

基础知识点

  1. 说明:构造函数名与类名相同,在创建对象的时候由系统自动调用,可用来进行成员初始化;
  2. 特点:无返回值;不可手工调用;一般public(单例模式是例外);
  3. 可重载:意味着一个类中可以有多个构造函数,差别在于参数列表;
  4. 无参构造函数就是默认构造函数;
  5. 存在继承关系,先执行父类构造函数,再执行子类构造函数;

重要语法

  1. 隐式转换:定义类的对象时,写作:classname test={参数列表};实际进行过隐式转换,为了防止隐式转换,可以在对应构造函数前加上关键字explicit;
  2. 初始化列表:冒号逗号式写法,写在构造函数参数列表后,真正的初始化({}中已经是赋值)在函数体执行之前就完成了,执行顺序与成员定义顺序相同;
  3. 类内初始值:C++11标准允许为类中成员赋初始值:int hours{5};
  4. const成员与自定义类型成员都要通过初始化列表进行初始化;

类中重点

inline 内联函数声明,标记在类外(直接在类中定义自动成为内联函数),但这仅仅是一种建议,具体成功与否取决于编译器;

mutable 可修改,与const正好相反。由于const函数不允许修改成员变量的值,但是有时候必须要修改某个成员变量,可以将该成员用mutable修饰:mutable int hours;

this指针 指向对象本身,有资料显示这个this是类成员函数隐含的第一个参数,会被传递到成员函数中,用以访问非static的成员;

static 静态成员与函数,由类独自享有,不属于对象;静态成员函数也一般只能操作静态成员,因为没有this指针不能访问一般成员;静态成员声明在类中:static int hours; 并在cpp中进行初始化int Time::hours=5;

default 简便指定默认构造函数:Time()=default;//则不用再进行函数实现,自动生成默认构造函数;

delete 显式禁用某个函数:Time()=delete;不让系统生成或使用默认构造函数;

拷贝构造函数

基础知识点

默认拷贝构造函数:无自定义时系统合成,类对象的成员逐个复制(赋值);

概念:第一个参数为所属类类型引用,若有其他参数必带默认值的构造函数为拷贝构造函数;

Time(const Time& time,int a=1);

什么时候调用拷贝构造函数?

  1. 同一语句里既有创建又有赋值就会调用拷贝构造函数:
  2. 类对象作为实参对形参进行值传递;
  3. 类对象作为返回值;

 隐式转换:单参数构造函数往往使用explicit防止;拷贝构造函数往往不使用explicit;

深拷贝与浅拷贝

针对指针:浅拷贝后两个指针指向同一个内存空间,深拷贝需要不但对指针进行拷贝,并对指针指向的内容进行拷贝,经过深拷贝后的指针是指向两个不同地址的指针。

析构函数

系统具有自动合成的析构函数(程序员不处理);

作用:用于释放内存等善后处理(如构造函数中有new的操作,使用析构进行delete防止内存泄漏),这种销毁并非在析构函数内,而是函数执行完成后由系统统一处理的销毁,且先定义先初始化,后销毁,这个顺序是反的。

调用:类对象离开作用域,自动调用;

重载:析构函数无返回值,无参数列表,不能重载;

虚函数:析构函数推荐设置为虚函数,保证父指针new的子对象(开辟的是子对象的空间)能调用到子对象的虚构函数(动态绑定);virtual ~Time();父类析构函数的virtual会继承给子类;

运算符重载

一般形式:returntype operator运算符(参数表)

bool operator==(Time& t);

bool Time::operator==(Time& t){

if(Hours==t.Hours)//this->Hours==t.Hours

return true;

return false;

}

类的赋值运算符重载:会有默认的赋值运算符重载(=),但是要实现更为复杂的功能时候要进行自定义,这是区别于拷贝构造函数的(也就是使用了赋值但没有创建不调用拷贝构造的情况)。

public://必定是public的,使用private就是禁用的意思了

Time& operator=(const Time&);

Time& Time::operator=(const Time& t){

//赋值逻辑

return *this;

}

要注意返回值类型(类型引用),参数列表(数据保护),this指针;

函数遮蔽

无论返回值与参数,只要父类与子类具有同名函数,子类函数就会遮蔽父类同名函数(一遮多):只要子类有一个和父类中同名的函数,子类调用就不可能调用到父类的同名函数(即使参数不同),如果仍要调用:子类对象名.父类名::函数名();进行调用;或者使用using函数允许父类同名函数与子类同名函数(但参数不同)构成重载:

public:

using 父类名::函数名;//此时就可以将父类同名函数拉取到子类,完全相同的遮蔽,参数不同的构成重载;

多态

父子指针

父类指针可以new一个子类对象:父类* ptr=new 子类();//子类可以看做具有冗余信息,完全能满足父类成员数据填充需求;是用子信息填充父信息,用法是父指针,数据是子类

子类指针不能new一个父类对象:子类* ptr=new 父类();//错误,存在缺失信息;

虚函数

一个函数一旦生命为virtual,子类不管是否标记都是虚函数;为了避免写错,一般在结尾加上override关键字;

子类虚函数与父类虚函数函数名与形参都要一样,这是与屏蔽对立的做法,一般称为重写;

运行时绑定(父指针与子对象),注意用法是父指针,数据(函数实现)是子类的含义;

总结:

父指针调用虚成员函数,动态绑定到给定对象的虚函数上;这就体现了同一个主体面对不同消息时的不同响应,这就是多态

执行虚函数来自于真实绑定的对象;

纯虚函数与抽象类

纯虚函数在父类中声明:virtual void func()=0;任何子类都要定义该虚函数的实现,否则还是纯虚函数(成为抽象类);

带纯虚函数就是抽象类,抽象类不能实例化对象;

友元

友元函数

类内 声明为友元函数friend void func();,则友元函数内可让类对象访问私有成员(不是成员函数不能绕过对象直接访问私有);

友元关系是单向的,保证数据安全;

友元类

class A{

friend class B;//B的成员函数范围内可让A对象访问私有成员等

}

 友元成员函数

仅仅是让B类部分成员函数成为A类友元函数;

 友元:提高了数据访问的灵活性,但是破坏了数据的封装;

猜你喜欢

转载自blog.csdn.net/weixin_44212242/article/details/125736916