您的位置:首页 > 编程语言 > C语言/C++

C++面向对象部分内容总结

2014-11-03 21:40 477 查看
类和对象

1、三种访问权限:private(默认)、protected、public;

2、对象成员的访问:”类内”指在类的成员函数中,“类外”指在类的成员函数之外,通过对象或对象指针访问对象的成员;

3、类成员的访问特性:在类内private、protected、public成员均可访问,在类外只能访问public成员;

4、构造函数:特点:函数名与类名相同,函数没有返回值,构造函数只能由系统自动调用,当构造函数有重载时,系统能自动根据所给参数的多少决定调用哪一个重载的构造函数,一般地,将构造函数定义成公有成员函数;

5、析构函数:析构函数不指定返回值类型,没有参数,一个类只能定义一个析构函数,即析构函数不允许重载,一般地,将析构函数定义成公有成员函数;

6、缺省构造函数:有两种:一、没有带参数的;二、带参数的,并且每一个参数都有默认值;

7、拷贝构造函数:函数名与类名相同,因为也是构造函数,该函数不被指定任何返回值类型,该函数只有一个参数,必须是本类对象的引用,每个类必须有一个拷贝构造函数,如果用户没有定义拷贝构造函数,则系统自动产生一个默认的拷贝构造函数,大部分情况下系统自动调用的拷贝构造函数可以完成拷贝功能,但是当类的数据成员中有动态申请的空间,则必须自己定义拷贝构造函数;

8、成员函数的特性:类的成员函数可以分为内联函数和外联函数,在类体内定义的成员函数是内联函数,在类体外定义的函数是外联函数;

9、成员函数的重载:判断重载的标准:函数名必须相同,函数参数类型或参数个数至少有一个不相同,跟返回值无关;

10、this指针:this指针是隐含于每一个类的成员函数中的特殊指针,该指针是一个指向正在被某一个函数操作的对象的指针,当对象调用该成员函数时,自动将对象自身的指针传递给该成员函数,在成员函数中可直接使用该指针,指针名为this;

类和对象的其他的特性

1、静态成员:静态成员是为了解决数据共享问题,静态数据成员是类的所有对象共享的成员,而不是某个对象的成员,在类中,静态成员分为静态数据成员和静态成员函数;

2、必须在类体外对静态数据成员进行初始化,初始化时,前面不需要加static,但应在静态数据成员名前加类名限定,以免与一般的全局静态变量混淆;

3、静态成员函数:静态成员函数也是属于类的静态成员,而不是属于对象的成员,因此,对静态成员函数的引用必须用类型限定,在静态成员函数的实现中,可以引用类中的静态成员,但不能直接引用类中的非静态成员,类的对象可直接调用静态成员函数;

4、友元函数:友元函数不是类的成员函数,因此,对友元函数指定访问权限无效,可以把友元函数的说明放在private、public、protected的任意段中;使用友元函数的目的是提高程序的运行效率;慎用友元函数,因为它可以在类外直接访问类的私有或保护成员,破坏了类的信息隐藏的特性;

5、友元类:友元还可以是类,即一个类可以作为另一个类的友元,当一个类作为另一个类的友元时,就意味着这个类的所有成员函数都是另一个类的友元函数;
继承和派生

1、继承有两种:单一继承和多重继承,当派生类仅有一个基类派生时,称为单一继承,当派生类由多个基类派生时,称为多重继承;

2、不同继承方式下基类和派生类成员的访问权限:不论何种继承方式,基类的private成员,在派生类中均不可直接访问,只有公有继承的基类的公有成员,在派生类中可直接访问,在公有继承的派生类中,保持基类的public成员和protected成员的属性,在私有继承的派生类中,将基类的public成员好protected继承均变成了私有成员,在保护继承的派生类中,将基类的public成员变成了保护成员,而protected成员仍然保持其属性;

3、基类成员的初始化:派生类构造函数的一般格式为:ClassName::ClassName(args):Base1(arg1),Base(arg2),...,Basen(argn){<派生类自身的构造函数体>},派生类构造函数的执行顺序为:先依次调用基类的构造函数Base1(),Base2(),...,Basen(),最后执行<派生类自身的构造函数体>,析构函数的调用顺序为:先执行派生类自身的析构函数体,然后按~Basen(),...,~Base2(),~Base1()的顺序调用基类的析构函数,调用基类的构造函数的顺序并不是由在写派生类的构造函数时后面接的基类的顺序决定的,而是由在定义派生类时的派生顺序决定的;

4、当派生类中有定义基类的对象时,在派生类的构造函数中,除了要加上基类的构造函数,还要加上基类对象的构造函数,C++系统处理成:先调用基类的构造函数,再调用对象成员的构造函数,最后调用对象自身的构造函数,并且调用构造函数的顺序由由派生类的派生顺序以及定义基类变量的顺序依次决定;

5、二义性(访问冲突):在多重继承中,当在派生类中出现两个以上同名的可直接访问的基类成员时,便出现了二义性,有时我们称为二义性访问冲突;

6、解决二义性一般有两种方法:一、在定义时,使得不同基类中的各成员,彼此之间不出现同名现象,显然,这不是一个好的解决办法;二、使用作用域运算符来限定所访问成员是属于哪一个基类的; 当把派生类作为基类,又派生出新的派生类时,这种限定作用域的运算符不能嵌套使用, 由于C++是通过作用域运算符来解决访问二义性问题,因此规定任一基类在派生类中只能被直接继承一次,否则会造成成员名访问的冲突;

7、支配规则:在C++中,允许派生类中新增加的成员名与其基类的成员名相同,这种同名并不产生访问二义性(或称访问冲突),在派生类中访问同名成员时,若没有使用作用域运算符,则访问的是派生类的成员,若使用了作用域运算符,则访问的是基类的同名成员,也就是说,对于同名成员的访问,派生类优先,这种优先关系称为支配规则;

8、虚基类:当B继承A,C继承A,并且D同时继承B和C时,这样就在D类中包含了基类A的两个拷贝,此时在D的成员函数中,若欲访问A的成员x,则必须以B::x和C::x区分,在多重派生中,若欲使公共的基类在派生类中只有一个拷贝,则可以将基类说明成虚基类,只要将基类的类名前加上关键字virtual即可,其一般格式为:class<类名>:virtual <继承方式><基类名>
注意:当分别调用B和C的构造函数来调用A的构造函数时,由于此时编译器无法确定应该是由B的构造函数还是由C的构造函数来调用A的构造函数,在这种情况下,C++约定调用A类的缺省构造函数

9、赋值兼容:在同类对象之间可以相互兼容,赋值兼容规则:可以将公有派生类对象赋值给基类对象,反之是不允许的;归纳为几点:1、派生类对象可以赋值给基类对象,系统将派生类对象中从基类继承来的成员赋值给基类对象;2、不能将基类对象赋值给派生类对象,因为派生类对象比基类对象“大”,如果赋值,则派生类对象“大”的部分将无法赋值;3、私有或保护继承的派生类对象,不可以赋值给基类对象;4、可以将派生类对象的指针赋值为基类的指针变量;5、派生类对象可初始化基类的引用;

多态性

1、多态性:多态性是面向对象程序设计的重要特性,它与封装性与继承性构成了面向对象程序设计的三大特性,这三大特性是互相关联的,封装性是基础,继承性是关键,多态性是补充;多态分为静态多态和动态多态,函数重载和运算符重载属于静态重载,动态多态是运行时的多态;

2、运算符重载:C++提供的运算符重载机制能够实现将已有运算符应用到新的数据类型变量上,但必须首先进行运算符重载的定义;在C++中可以重载的运算符有40个,不能重载的运算符有5个,为条件运算符:?:成员运算符:.取指向内容运算符:*作用域运算符:::求字节数运算符:sizeof;重载运算符的限制:1、只能对已有运算符重载,不可以臆造新的运算符;2、重载运算符时,不允许改变运算符的优先级和结合性;3、重载运算符时,不允许改变运算符的语法结构,如二元运算符只能重载成二元运算符;

3、运算符重载的三种方式:运算符重载的原理是:一个运算符是一个具有特定意义的符号,只要告诉编译器在什么情况下如何去完成特定的操作,而这种操作是通过特定的函数来实现的; 运算符重载的形式:成员函数形式、友元函数形式、一般的运算符重载函数(非友元、非成员)

4、运算符重载的三种方式比较:对于一般的二元运算符重载为友元函数比重载为成员函数更优越,但是对于赋值运算符,将其重载为成员函数较好,当在类中没有定义赋值运算符的重载函数时,一般情况下C++的默认赋值处理是不会出现问题的,但是当对象中有指针成员指向动态分配的内存,就会出现问题,这时必须要自己重载等号运算符;一般的重载运算符(非友元、非成员)和友元函数差不多,但是效率较低;

5、联编:联编是一个计算机程序彼此关联的过程,在本书中指的是函数间调用关系的确定,按照联编所确定的时刻不同,可以分为静态联编和动态联编;

6、静态联编:指联编出现在编译连接阶段,这种联编又称为早期联编,通过这种联编可以实现静态多态,如函数重载,运算符重载是通过函数重载实现的,所以统称为函数重载;

7、动态联编和虚函数:程序中若出现函数调用,但在程序的编译阶段无法确定调用哪一个函数,而只有到了程序的运行阶段才能确定调用的是哪一个函数,这就是动态联编,动态联编又称为滞后联编、晚期联编,动态联编能实现动态多态,C++中提供动态联编技术,它必须将类的成员函数定义为虚函数,才可以实现动态联编;

8、关于虚函数注意的几点:1、当基类中把成员函数定义为虚函数后,在其派生类中的虚函数必须与基类中的虚函数同名,且函数的参数个数、参数类型必须完全一致,否则属于函数的重载,而不是能实现动态多态的虚函数;2、基类中虚函数前的关键字virtual不能省略,派生类中虚函数前的关键字virtual可以省略,缺省后仍然是虚函数;3、动态多态必须通过基类对象的引用或基类对象的指针调用虚函数才能实现;4、虚函数必须是类的成员函数,不能是友元函数,也不能是静态成员函数;5、不能将构造函数定义为虚函数,但可以将析构函数定义为虚函数,如果类的构造函数中有动态申请的存储空间,则在析构函数中释放该空间,此时建议将析构函数定义为虚函数,以便实现撤销对象时的多态性;6、虚函数与一般函数相比,调用时的执行速度要慢一些,因为为了实现动态联编,在每个派生类中都要保存相应虚函数的入口地址,而且函数的调用机制也是间接实现的;

9、纯虚函数:纯虚函数的一般格式为:virtual <函数返回值类型> <函数名>( [<参数列表>] )=0; 函数参数列表圆括号后面的“=0”,表示将函数名的值赋予0,就是将指向函数体的指针赋初值0,它无法调用任何函数,这与将虚函数定义成空函数是有区别的;

10、抽象类:含有纯虚函数的类称为抽象类, 注意点:1、抽象类只能做派生类的基类,不能定义抽象类的对象;2、在抽象类的派生类中,如果没有对基类的纯虚函数的定义实现函数,那么它仍然是抽象类;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: