(一)重载运算符: (1)声明与定义格式 一般是类内声明,类外定义,虽然可以在类内定义,但 写前面堆一堆不好看!!!...)双目运算符重载为成员函数 当重载运算符为双目运算符时,形参表中只有一个参数作为右操作数。...(3)单目运算符重载为成员函数 此时参数表中没有参数,只有当前对象作为运算符的一个操作数。...(2)派生类的生成过程 吸收基类成员:除构造和析构函数外 改造基类成员:通过在派生类中定义同名成员屏蔽基类成员在派生类中直接调用,仍可以基类指针调用同名成员 .添加新成员 (3)派生类特点 子类拥有父类除了父类构造和析构函数...2、在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
但如果基类没有合适的默认构造,那则必须在派生类的初始化列表显示调用基类的有参构造函数进行基类成员的初始化。 2....拷贝构造函数与构造不同,必须在派生类的拷贝构造的初始化列表处显示调用基类的拷贝构造,完成基类成员的复制。在传参时有人可能会有疑问,调用基类的拷贝构造该如何将子类中基类成员提取出来呢?...但和复制重载相同的是,在调用基类赋值函数进行传参时,所采取的策略依旧是向上切割赋值。 4....基类若定义出一个静态成员,则在继承体系里面有且仅有这样一个静态成员,无论基类派生出多少子类,都只有一个static成员实例。 2....而这个内存地址只有一份,所以这就解决了数据冗余的问题,因为内存中不再像原来一样,派生类中分别存储虚基类成员导致数据冗余,而是仅仅只存一份虚基类成员,派生类改为存储虚基类指针。 4.
基类成员与继承方式的关系共有9种,见下表: 虽然说是有9种,但其实最常用的还是红框里的,其它的很少用。 ...隐藏(重定义)与重载 重载:在同一作用域; 隐藏:在不同的作用域,一个在父类,一个在子类。...2.拷贝构造 派生类的拷贝构造必须先调用基类的拷贝构造完成基类的拷贝初始化。 3.赋值重载 派生类赋值重载必须先调用基类的赋值重载完成基类的复制。...main() { A a; B b; return 0; } 六.继承与友元,静态成员 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员; 基类定义了static静态成员,则整个继承体系里面只有一个这样的成员...无论派生出多少个子 类,都只有一个static成员实例 ,静态成员不属于任何一个具体的实例对象,而是属于类本身,子类可以继承父类的静态成员,而不需要重新定义。
重载 overload,指对一个同名方法进行了几种不同参数的实现 可以将一个派生类对象转换为基类对象,此时派生类独有的部分将被截断,其基类部分被处理而派生类部分被忽略 有时我们不希望派生类独有的部分被截断则需要使用类指针来调用重载的函数或使用指针所指的成员...每次继承一个基类就会在内存中生成一个子对象,存放了基类的成员,也正是因为这个原因派生类可以转换为基类 派生类的构造函数需要负责所有成员的初始化,尽管派生类也可以初始化继承来的基类成员,但是这不符合通常的编码思路...因此除了重载虚函数外最好不要让名称同名 派生类可以覆盖基类重载的函数,但是如果派生类希望基类重载的几个函数都在派生类中可见的话:一种方法是不覆盖任何一个重载函数或将所有重载函数都进行一次覆盖;另一种方法是为需要重载的函数名使用...,对于实现的内容我们一样可以使用=default简化 如果基类中的基本操作函数不可访问或被删除,则派生类中的对应成员是被删除的因为我们无法使用基类来操作那些成员 C11中,我们可以用using重用基类定义的构造函数...(都是为了可以在编译期完成所要求的) 模板的提供者必须保证模板实例化时依赖于模板参数的名字都必须有定义,其他的要保证对编译器可见 类模板不会推断参数的类型 类模板的成员函数只有在使用时才会实例化 类模板与另一个模板直接最常见的友元是一对一的友元
,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数进行重新定义。...如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数 虚函数可以让成员函数操作一般化,用基类的指针指向不同的派生类的对象时,基类虚成员函数调用基类指针,则会调用其真正指向的对象的成员函数,而不是基类中定义的成员函数...若不是虚函数,则不管基类指针指向哪个派生类对象,调用时都会调用基类中定义的那个函数 Tip: 虚函数的引入就是为了实现多态的特性,让不同的子类可以有不同的实现方式 ---- 纯虚函数 纯虚函数是一种特殊的虚函数...2)虚函数在子类里面也可以不重载的;但纯虚必须在子类去实现,这就像Java的接口一样。...,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是 public static final 类型,并且默认即为 public static final 类型 ---- 虚基类 虚基类是一个相对概念
当派生类中定义与父类同名的成员时,派生类将屏蔽对基类该成员的直接访问,称这种情况为隐藏。而派生类中的同名成员是对基类成员的重写/重定义。...如果要在派生类中访问父类的成员,可以使用:基类::基类成员这种方式显示访问。 如果是成员函数的隐藏,则只需要函数名相同即可构成隐藏。 注意:在实际应用中尽量避免定义同名成员。...fun函数并不构成重载,因为他们在不同的作用域,他们是隐藏关系 四、派生类的默认成员函数 1.构造函数 派生类构造函数必须调用基类的构造函数初始化基类那一部分成员,如果基类没有默认构造函数,派生类就必须在初始化列表处显示的调用基类构造函数...五、友元 友元关系不能继承,即基类的友元不能访问派生类的private和protected成员 六、静态成员 基类的静态成员,在整个继承体系中都只有一个这样的成员,即无论有多少个派生类,都只有一个static...七、菱形继承和菱形虚拟继承 1.单继承 一个派生类只有一个直接基类,这种称为单继承。 2.多继承 一个派生类有多个直接基类,这种情况称为多继承。
文章目录 一、继承的概念及定义 1、继承的概念 2、继承的定义 二、基类和派生类对象的赋值 三、继承中的作用域 1、继承中的作用域 (隐藏) 2、经典面试题 四、派生类的默认成员函数 五、继承与友元...2、基类 private 成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出 protected 限定符是因继承才出现的。...重载 B. 重写 C.重定义/隐藏 D....在继承中,如果父类定义了 static 静态成员,则该静态成员也属于所有派生类及其对象;即整个继承体系里面只有一个这样的成员,并且无论派生出多少个子类,都只有一个 static 成员实例; class...; // 学号 }; 可以看到,父类和子类在操作时操作的都是同一个静态成员实例,因为父类和子类中静态成员是同一个地址;所以,静态成员属于所有父类及其对象,以及所有派生类及其对象,且只有一份。
运算符重载函数作为 类成员函数 与 友元函数(形参必须有要求) 一般将单目运算符和复合运算符重载为成员函数 一般将双目运算符重载为友元函数; 重载双目运算符 C++构造函数的重载 在一个类中可以定义多个构造函数...如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。 定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。...需要说明;有时在基类中定义的非虚函数会在派生类中被重新定义(如例12.1中的area函数),如果用基类指针调用该成员函数,则系统会调用对象中基类部分的成员函数;如果用派生类指针调用该成员函数,则系统会调用派生类对象中的成员函数...Tips: 1)只能用virtual声明类的成员函数,把它作为虚函数,而不能将类外的普通函数声明为虚函数; 2)一个类的成员函数被声明为虚函数后i,在同一类族中的类就不能再定义一个非virtual的但与该函数具有相同的参数和函数返回值类型的同名函数...通常来说,如果基类中存在一个指向动态分配内存的成员变量,并且基类的析构函数中定义了释放该动态分配内存的代码,那么就应该将基类的析构函数声明为虚函数。
protected(保护)访问修饰符与私有访问修饰符类似,但允许派生类(子类)访问基类中的保护成员。...成员声明列表中包含类成员变量以及成员函数,是派生类新增的成员。 “:”是一个运算符,表示基类和派生类之间的继承关系。...只有通过基类指针或引用调用虚函数才能引发动态绑定 虚函数不能声明为静态 如果一个类要做为多态基类,要将析构函数定义为虚函数 虚表指针 虚函数的动态绑定是通过虚表来实现的 包含虚函数的类头4个字节存放指向虚表的指针...派生类中必须实现基类中的纯虚函数,否则被看做一个抽象类 对于一个没有任何接口的类,如果想要将它定义成抽象类,只能将虚构函数声明为纯虚的 通常情况下在基类中纯虚函数不需要实现,例外是纯析构函数要给出实现...重载 在C++中,函数重载(Function Overloading)是指在同一个作用域内,可以定义多个具有相同名称但参数列表不同的函数。
例如在例12.1(具体代码请查看:C++多态性的一个典型例子)程序中,在Circle类中定义了 area函数,在Circle类的派生类Cylinder中也定义了一个area函数。...要注意的是,只有用virtual声明了虚函数后才具有以上作用。如果不声明为虚函数,企图通过基类指针调用派生类的非虚函数是不行的。 虚函数的以上功能是很有实用意义的。...如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。 定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。...需要说明;有时在基类中定义的非虚函数会在派生类中被重新定义(如例12.1中的area函数),如果用基类指针调用该成员函数,则系统会调用对象中基类部分的成员函数;如果用派生类指针调用该成员函数,则系统会调用派生类对象中的成员函数...但与重载不同的是:同一类族的虚函数的首部是相同的,而函数重载时函数的首部是不同的(参数个数或类型不同)。
派生类经常会覆盖继承的虚函数,但如果派生类没有覆盖,则这个函数将会被直接继承,可以被普通地使用 派生类可以继承多个基类,称为多继承。...每次继承一个基类就会在内存中生成一个子对象,存放了基类的成员,也正是因为这个原因派生类可以转换为基类。如果是对象转换到对象,那多余的成员会被截断。...,让基类来初始化自己的成员 派生类可以使用基类的public成员和protected成员 如果基类定义了一个静态成员,那整个继承体系中都只会有这成员的唯一定义,无论派生了多少类这个成员都是唯一实例的,静态成员也同样遵循访问控制原则...因此基类和派生类的虚函数形参应该相同 派生类可以覆盖基类重载的函数,但是如果派生类希望基类重载的几个函数都在派生类中可见,避免名称隐藏的话:一种方法是不覆盖任何一个重载函数或将所有重载函数都进行一次覆盖...因此编译器在构造和析构的时候只往基类搜索来得到所需的成员 C11中,我们可以用using重用基类定义的构造函数,写法和15.6中指明重载的基类函数一样,效果与定义一个空的构造函数然后列表中调用基类构造函数一致
浏览量 1 友元函数必须在类中进行声明而在类外定义,声明时须在函数返回类型前面加上关键字friend。友元函数虽不是类的成员函数,但它可以访问类中的私有和保护类型数据成员。...虚函数在重新定义时参数的个数和类型必须和基类中的虚函数完全匹配,这一点和函数重载完全不同。...覆盖(Override)是指派生类中存在重新定义的函数,其函数名、参数列、返回值类型必须同父类中的相对应被覆盖的函数严格一致,覆盖函数和被覆盖函数只有函数体 (花括号中的部分)不同,当派生类对象调用子类中该同名函数时会自动调用子类中的覆盖版本...下面我们从成员函数的角度来讲述重载和覆盖的区别。 成员函数被重载的特征有: 相同的范围(在同一个类中);2) 函数名字相同;3) 参数不同;4) virtual关键字可有可无。...隐藏是指派生类的函数屏蔽了与其同名的基类函数,规则如下: 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
C++进阶-多态 零、前言 一、多态的概念和定义 二、虚函数 1、概念和定义 2、虚函数重写的特例 3、C++11 override 和 final 4、重载/重写/重定义对比 三、抽象类 四、多态的原理...,且派生类必须对基类的虚函数进行重写 示图: 二、虚函数 1、概念和定义 虚函数语法: 被virtual修饰的类成员函数称为虚函数 示例: class Person { public:...virtual,派生类的虚函数加virtual,这种情况是不构成虚函数的 析构函数的重写 我们知道,基类指针和引用可以指向基类和派生对象,由此通过指针和引用释放对象时需要实现析构的多态,但基类与派生类析构函数名字不同...一般情况这个数组最后面放了一个nullptr(用来表示结束)(可能根据编译器而定) 派生类的虚表生成总结: 先将基类中的虚表内容拷贝一份到派生类虚表中 如果派生类重写了基类中某个虚函数,...重载:在同一作用域中,函数名相同和参数不同构成重载 重写:在基类和继承类域中,对于虚函数,函数名,参数和返回值相同(特例除外),构成重写 重定义:在基类和继承类域中,函数名相同,不构成重载就构成重定义
初始化顺序由定义顺序决定,而不是初始化列表顺序。 友元:将非公有成员的访问权授予指定的类或函数。friend在类定义内部。友元引入的类名和函数(定义或声明)可以像预先声明的一样使用。...根类一般要定义虚析构函数。 派生类只能通过派生类对象访问protected成员,不能用基类对象访问。基类定义为virtual就一直为虚函数,派生类写不写virtual都是虚函数。...派生类继承基类的访问控制标号【何种方式继承】无论是什么,不影响派生类使用基类成员,但影响使用派生类的用户访问基类成员。类使用接口继承还是实现继承对派生类用户具有重要含义。 友元关系不继承。...派生类析构函数不负责清除基类成员,每个析构函数只负责清除自己成员。...局部作用域中声明的函数不会重载全局域的函数。派生类定义的函数也不重载基类函数【想重载要么不定义,要么全定义】。using作用域。
默认情况 基类的构造函数不被继承 派生类需要定义自己的构造函数 C++11规定 可用using语句继承基类构造函数 但是只能初始化从基类继承的成员 派生类新增成员可以通过类内初始值进行初始化 语法形式...: using B::B; 多继承且有对象成员时派生的构造函数定义语法 派生类名::派生类名(形参表): 基类名1(参数), 基类名2(参数), ..., 基类名n(参数), 本类成员(含对象成员)初始化列表...,由初始化列表提供参数 执行派生类的构造函数体中的内容 派生类复制构造函数 派生类未定义复制构造函数的情况 编译器会在需要时生成一个隐含的复制构造函数 先调用基类的复制构造函数 再为派生类新增的成员执行复制...派生类定义了复制构造函数的情况 一般都要为基类的复制构造函数传递参数 复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数 基类的复制构造函数形参类型是基类对象的引用...如要通过派生类对象访问基类中被隐藏的同名成员,应使用基类名和作用域操作符(::)来限定 如果从不同基类继承了同名成员,但是在派生类中没有定义同名成员,“派生类对象名或引用名.成员名”、“派生类指针->
) class person { }; class student : public person //公有继承(最多) { //基类的私有成员不能用派生类新定义的成员函数去访问,只能通过继承过来的成员函数去访问基类私有成员数据...//虚函数要和基指针结合使用(可是实现基指针指向派生类对象时,可以调用该对象重新写后的函数内容) //虚函数实现原理(每个类中都有一个虚表存放虚函数,一旦在某类被重新定义,该类虚表就会更新,指针调用的就是虚表里的函数...参数表 ) =0; //在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进行定义。...delete p;//基指针指向过基类、派生类,需要定义基类析构函数为虚函数,否则,执行该操作后,只释放基类内存,可能会内存泄漏 } //多态性 //静态多态性:函数重载、运算符重载 //动态多态性:...但考虑到各方面的因素,一般将单目运算符重载为成员函数,将双目运算符重载为友元函数。
基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。...而现在我们学习了继承,知道基类可以传给派生类成员变量以及成员函数,但这默认成员函数对于每一个类来说都必须是自己的,并且基类的成员变量有可能比派生类的成员变量的数量不匹配,种种情况都表明,派生类的默认成员函数不能使用基类的默认成员函数...4.3 派生类的赋值运算符重载 不写这个函数调用默认的赋值运算符重载,情况和拷贝构造一样,成员变量中含自定义变量则不能处理。...基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。...如果是相同类的赋值,根本不需要这样的东西,而上面谈到过,将派生类赋值给基类会发生切片,切片就会导致等号两边的对象的成员变量的相对位置会发生变化,由于A地址只有一个,此时如果仍要找到该成员变量的位置,就需要一个数据记录下来之前的相对位置
这里简单做一个总结: 在基类的方法声明中使用关键字virtual可以声明虚函数 加上了virtual关键字的函数在基类以及派生类和派生类再派生出来的类中都是虚的 在调用虚函数时,程序将会根据对象的类型执行对应的方法而非引用或指针的类型...在定义基类时,需要将要在派生类中重新定义的类方法声明为虚,如析构函数 除了这些之外,我们还有一些其他需要注意的事项。...因为派生类当中往往含有独有的成员变量,如果析构函数非虚,那么会导致在对象析构时仅调用基类的析构函数,从而导致独有的成员变量内存不被释放,引起内存泄漏。...友元 友元函数不能是虚函数,因为友元不是类成员,只有成员函数才能是虚函数。 如果我们希望友元函数也能实现类似虚函数的功能, 我们可以在友元函数当中使用虚函数来解决。...没有重新定义 如果派生类当中没有重新定义虚函数,那么将使用该函数的基类版本。如果派生类位于派生链中,如B继承了A,C继承了B这种情况,那么派生类将会使用最新的虚函数版本。
它可以在派生类中重新定义,以形成不同版本。只有在程序的执行过 程中,依据指针具体指向哪个类对象,或依据引用哪个类对象,才能确定激活哪一个版本,实现动态聚束。...若函数名相同,但参数的个数不同或者参数的类型不同时,则属于函数的重载,而不是虚函数。若函数名不同,显然这是不同的成员函数。...3、虚函数必须是类的一个成员函数,不能是友元函数,也不能是静态 的成员函数。 4、在派生类中没有重新定义虚函数时,与一般的成员函数一样,当调 用这种派生类对象的虚函数时,则调用其基类中的虚函数。...这种类只能作为派生 类的基类,不能用来创建对象。 其理由是明显的:因为虚函数没有实现部分,所以不能产生对象。但 可以定义指向抽象类的指针,即指向这种基类的指针。...当用这种基类 指针指向其派生类的对象时,必须在派生类中重载纯虚函数,否则会 产生程序的运行错误。 4、在以抽象类作为基类的派生类中必须有纯虚函数的实现部分,即必 须有重载纯虚函数的函数体。
文章目录 前言 一、面向对象 二、使用类 1.类的基础使用 2.运算符重载 3.友元 1.友元函数 2.友元类 3.友元成员函数 三、类继承 基类 派生类 插个访问权限的事情 2.多态 ***公有 **...析构:首先调用派生类析构函数,然后再调用基类析构函数 2.多态 ***公有 *** 继承 当需要同一个方法再派生类和基类中行为是不同的,或者说方法的行为应取决于调用该方法的对象——多态,多种状态 在派生类中重新定义基类...注意:如果在派生类中重新定义基类的方法,通常将基类方法声明为虚的,好处是程序将根据对象类型而不是引用或者指针的类型来选择方法版本,算是一个惯例吧 函数实现我就不写了,不然篇幅太长了,感谢!...在c++中,一个基类的指针或者引用可以指向或者引用派生类的对象。同时,派生类可以重写基类中的成员函数。...这样就可以将基类与派生类的同名方法区分开,实现多态。 3.抽象基类 不能实例化的基类被称为抽象基类, 这样的基类只有一个用途, 那就是从它派生出其他类。
领取专属 10元无门槛券
手把手带您无忧上云