抽象类的定义: 称带有纯虚函数的类为抽象类 抽象类的作用 抽象类的主要作用是将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为借口的操作...使用抽象类时注意: 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然是一个抽象类。...实现了纯虚函数的子类,该纯虚函数在子类中就变成了了虚函数,子类的子类可以覆盖该虚函数,由多态方式调用的时候动态绑定。 虚函数是C++中用于实现多态的机制。核心理念就是通过基类访问派生类定义的函数。...在有动态分配堆上内存的时候,析构函数必须是虚函数,但没有必要是纯虚的。 友元不是成员函数,只有成员函数才可以使虚拟的,因此友元不能是虚拟函数。...但可以通过让友元函数调用虚拟成员函数来解决友元的虚拟问题。 析构函数应当是虚函数,将调用相应对象类型的析构函数。因此,如果指针指向的是子类对象,将调用子类的析构函数,然后自动调用基类的析构函数。
通常情况下只有成员函数(或者友元)中的代码才需要使用作用域运算符来回避虚函数的机制。...受保护成员 一个protected关键字声明它希望与派生类分享但是不想被其他公共访问使用的成员: 和私有成员类似,受保护的成员对于类的用户来说不可访问 和公有成员类似,受保护的成员对派生类的成员和友元来说是可访问的...派生类向基类转换的可访问性 假定D继承B: 只有当D公有地继承B时,用户代码才能使用派生类向基类的转换;如果D继承B的方式是受保护的或者私有的,则用户代码不能使用该转换 无论D以什么方式继承B,D的成员函数和友元都能使用派生类向基类的转换...;派生类向其直接基类的类型转换对于派生类的成员和友元来说永远是可访问的 如果D继承B的方式是公有的或者受保护的,则D的派生类的成员和友元可以使用D向B的类型转换,反之如果D继承B的方式是私有的,则不能使用...对于前者应该声明为受保护的,这样派生类就能在实现自己的功能时使用基类的这些操作和数据;对于后者应该声明为私有的。 4. 友元与继承 就像友元关系不能传递一样,友元关系同样也不能继承。
友元函数 内联函数 类的静态成员 类访问修饰符 继承 特点 基类/派生类 多继承 运算符/函数重载 多态 类和结构体的区别 C++ 中保留了C语言的 struct 关键字,并且加以扩充。...尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。 友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。...只有当函数只有 10 行甚至更少时才将其定义为内联函数. 类的静态成员 静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。...Protected成员变量或函数与私有成员十分相似,但有一点不同,protected(受保护)成员在派生类(即子类)中是可访问的。...成员只能被本类成员(类内)和友元访问,不能被派生类访问; 2.protected 成员可以被派生类访问。
,这个绑定在运行时才会确定,因此我们必须对每个虚函数都进行定义因为对虚函数的调用在运行时才解析,编译器也不能确定是否会被用到 运用这个动态绑定就是C++OOP的核心,多态性 一个派生类的函数如果想要覆盖继承来的虚函数...=0,我们只能对虚函数使用这个写法 我们也可以为纯虚函数写定义,但是定义必须写在类外 15.5 访问控制和继承 访问控制中最难理解的是protected,这表示那些希望与派生类和友元分享使用但不希望被公共函数使用的成员...派生类可以自己将某些函数写为friend,这样会获得其基类的protected权限 友元只对被声明的类有效,友元的基类或派生类都不是友元 派生类的成员和友元只能通过派生类对象来访问基类的protected...也就是当一个派生类与基类声明为友元,此时想要访问基类的保护成员时,必须通过派生类作为中介而不能直接用基类来访问,即使在成员函数中。详细如下 ?...,其余时候都不能转换 无论是什么继承,派生类和友元都可以在成员中使用派生到类的转换 public和protected继承时,派生类自己的派生类和友元可以使用派生到基类的转换,private则不行 总结起来
,此时我们把类A的析构函数修改为virtual,看看结果: A() B() ~B() ~A() 一般情况下,只有当一个类被用作基类时才需要使用虚析构函数,这样做的作用是当一个基类的指针删除派生类的对象时...以上三种情况都必须使用初始化列表而不能在构造函数中进行赋值。 10. 什么情况下要使用虚继承? 多重继承时需要使用虚继承,一般的我们在多重继承时使用虚继承来防止二义性问题。...友元类是什么 与友元函数类似,在一个类A中声明另外一个类B为friend类型,那么这个类B就是友元类,它访问类A的私有成员和保护成员都不受限制。...有关友元详细说明,请看这篇文章:c++类访问权限及友元 19....友元是否违反了封装的原则 违反了,友元函数可以不受访问权限的限制而访问类的任何成员,也就是它可以直接接触类的实现,当然违反了封装的原则,只是有时基于我们自身的某些使用场景,不得不使用友元。 20.
(取权限小的那个) 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。...继承与友元 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员 class Student; class Person { public: friend void Display(const..._stuNum << endl; } int main() { Person p; Student s; Display(p, s); } 不能访问父类的友元: 想要访问父类的友元,那么直接让这个函数也成为子类的友元...: 一个类可以同时是多个类的友元函数。...为了解决这个问题提出了虚继承。 虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。
接下来我们来分析一下友元函数的特点。 1、为什么要引入友元函数: 在实现类之间数据共享时,减少系统开销,提高效率。具体来说:为了使其他类的成员函数直接访问该类的私有变量。...2)两个类要共享数据的时候 3、友元方式的缺点: 1)友元函数破环了封装机制,除非不得已的情况下才使用友元函数。 2.友元关系与面向对象: 接下来我们聊聊怎么从面向对象的角度去理解友元关系。...所以如果本身代码风格趋近与面向对象的风格,就应该尽量理由友元类来实现需要的功能,而不是使用友元函数。...看起来并不会破坏上文提到的面向对象的逻辑了,但是涉及到继承又存在一些不大不小的坑,我们一起来捋一捋: 友元关系不能继承。基类的友元对派生类的成员没有特殊访问权限。...如果基类被授予友元关系,则只有基类具有特殊访问权限,该基类的派生类不能访问授予友元关系的类。
假定 D继承自 B: 只有当 D公有地继承 B时,用户代码才能使用派生类向基类的类型转换;如果 D继承 B的方式是受保护的或私有的,则用户代码不能使用该转换。...不论 D以什么方式继承 B,D的成员函数和友元都能使用派生类向基类的类型转换;派生类向其直接基类的类型转换对于派生类的成员和友元来说永远是可访问的。...如果 D继承 B的方式是公有或受保护的,则 D的派生类的成员和友元可使用 D向 B的类型转换;反之,如果 D继承 B的方式是私有的,则不能使用。 就像友元关系不能传递一样,友元关系同样也不能继承。...基类的友元在访问派生类成员时不具特殊性,类似的,派生类的友元也不能随意访问基类的成员。但是基类的友元是可以访问内嵌在派生类对象中的基类成员。...派生类定义的构造函数与基类的构造函数具有相同的形参列表时,则该构造函数不会被继承,派生类中使用的是自己定义的相应函数。 默认、拷贝和移动构造函数不会被继承,这些构造函数按照正常规则被合成。
文章目录 前言 一、面向对象 二、使用类 1.类的基础使用 2.运算符重载 3.友元 1.友元函数 2.友元类 3.友元成员函数 三、类继承 基类 派生类 插个访问权限的事情 2.多态 ***公有 **...意义:如果不做特殊处理,C++ 的 +、-、*、/ 等运算符只能用于对基本类型的常量或变量进行运算,不能用于对象之间的运算,运用与对象处理 3.友元 怎么说这个呢?...平常不用,但是有一种地方用了更好:公有类方法提供了唯一的访问途径,但是有时候不太适用于特定的问题,友元就出现了 1.友元函数 可以看为类的扩展接口,直接用吧: //创建友元函数是将其放入类声明中 class...当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。...(继承了基类的实现) 派生类还继承了基类的接口 当然派生类和其他类的使用方法大致一样:可以有自己的构造函数,可以添加额外的数据成员和成员函数 插个访问权限的事情 首先派生类不能直接访问基类的私有成员,
4.3 string类 4.4 向函数传递对象 4.5 静态成员 4.6 友元 友元函数 友元类 4.7 类的组合 4.8 共享数据的保护 五、继承与派生 5.1 继承与派生的概念 基类成员在派生类中的访问属性...友元包括友元函数和友元类。 友元函数 友元函数既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数。...尤其当一个函数需要访问多个类时,友元函数非常有用,普通的成员函数只能访问其所属的类,但是多个类的友元函数能够访问相关的所有类的数据。...//声明类Y为类X的友元类 }; 当一个类被说明为另一个类的友元类时,它所有的成员函数都成为另一个类的友元函数,这就意味着作为友元类中的所有成员函数都可以访问另一个类中的所有成员。...若基类使用默认构造函数或不带参数的构造函数,则在派生类中定义构造函数时可略去“:基类构造函数名(参数表)”,此时若派生类也不需要构造函数,则可不定义构造函数。
此时基类可以通过指针或引用指向派生类(相当于将派生类从基类中继承的那部分方法和成员绑定到基类上了,相当于派生类被截断了),然后基类就可以将派生类假装是一个基类对象来使用(调用其中的成员/方法) ②为什么基类不能转换为派生类...三、继承方式对类型转换的影响 遵循下面3个规则: 假设B继承于A ①只有当B公有地继承A时,用户代码才能使用派生类向基类转换;如果B是受保护的/私有的继承于A,则不能使用派生类向基类转换 因为保护或者私有继承...A,B的成员函数和友元中可以将派生类对象向基类转换 class A{}; class B :protected A { void func() { A *a; B b; a = &b; //正确,成员函数内可以...a = this; //正确,成员函数内可以 } friend void func2(); //友元函数 }; void func2() { A *a; B b; a = &b; //正确,友元函数内可以...} int main() { A *a; B b; a = &b; //错误,因为为保护继承 return 0; } ③如果B继承于A的方式是公有的或者受保护的,则B的派生类的成员和友元可以使用B向A
基类的其他成员在子类的访问方式相等于Min(成员在基类的访问限定符,继承方式),public > protected > private 使用关键字class时默认的继承方式是private,使用...在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用...原则: 父类那部分调用父类的对应函数完成 5.继承与友元 友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员 class A { public: int _pa; friend...void print(B& bb);//这个print是A的友元 protected: int _a; }; class B :public A { public: int _pb; protected...如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承(在:后面加上virtual),即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用。
使用友元类时注意: (1) 友元关系不能被继承。 (2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。 (3) 友元关系不具有传递性。...4.类必须将重载函数集中每一个希望设为友元的函数都声明为友元。 5.友元关系不能继承,基类的友元对派生类的成员没有特殊的访问权限。如果基类被授予友元关系,则只有基类具有特殊的访问权限。...// 在多继承时,如果省略继承方式,默认为private // 如果在派生类中声明了一个与基类成员相同名字的函数,派生类的新成员会覆盖基类的同名成员 /* 不管何种继承 基类的私有程序都不能被派生类继承...否则会破坏C++的封装特性 * 基类的友元函数也不能被继承,友元只是能访问指定类的私有和保护成员的自定义函数,不是被指定类的成员,自然不能继承 * 基类与派生类的静态成员函数与静态成员是共用一段空间的...编译器确保当对象为派生类时,派生类的实现总是被调用,即使对象是使用基类指针访问而不是派生类的指针。
4.1 派生类的构造函数 4.2 派生类的拷贝构造函数 4.3 派生类的赋值运算符重载 4.4 派生类的析构函数 4.5 总结 五.继承与友元 六.继承与静态成员 6.1 静态成员 6.2 确定是否为解引用...下面我们使用监视窗口查看Student和Teacher对象,可 //以看到变量的复用。调用Print可以看到成员函数的复用。...使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。...五.继承与友元 核心关系:友元关系不能继承。...因此,需要将Display同时作为两个类的友元,这样才不会出错: class Student; class Person { public: friend void Display(const Person
- 派生类需要添加自己的__构造函数__ - 创建派生类对象时,程序首先创建基类对象 - 要通过初始化表用__基类的构造函数__给继承过来的成员变量提供初始值 - 如果省略了基类的初始化表,程序会使用基类的默认构造函数...构造函数不能是虚函数 -- 构造函数不继承基类的构造函数 -- 而是会调用基类的构造函数 - 基类的析构函数应该是虚函数 -- 即使它不执行任何操作 - 友元函数不能是虚函数 -- 友元不是类成员 --...友元函数可以使用虚成员函数 - 重新定义继承的函数但参数列表不同,派生类将隐藏同名的基类方法 - 所以如果要重新定义继承的函数,应确保与原来的原型完全相同 - 但如果该函数返回类型是基类的引用或指针,...,则该函数仍为纯虚函数发,派生类也为抽象类 - 基类中也可以定义(实现)纯虚函数,但在派生类中必需显示地调用(使用类名限定符) - 这样可以将不同子类中公共的事务放在父类中完成 - 只有声明而没有定义的纯虚函数派生类是无法调用的...在派生类的友元函数中, 只能访问派生类的派生部分,而不能访问基类的私有成员 可使用基类的友元函数来负责对派生类的基类部分的访问 - 但是需要强制类型转换 -- 友元函数无法使用类名限定符
一、虚函数 概念:在函数前面加virtual,就是虚函数 虚函数的一些概念: 只有成员函数才可定义为虚函数,友元/全局/static/构造函数都不可以 虚函数需要在函数名前加上关键字virtual 成员函数如果不是虚函数...{}; virtual B& func() {}; //重写了基类的虚函数 }; 二、为什么要设计虚函数 我们知道派生类会拥有基类定义的函数,但是对于某些函数,我们希望派生类各自定义适合于自己版本的函数...和其他函数一样,虚函数也可以拥有默认实参,使用规则如下: 如果派生类调用虚函数没有覆盖默认实参,那么使用的参数是基类虚函数的默认实参;如果覆盖了虚函数的默认实参,那么就使用自己传入的参数 派生类可以改写基类虚函数的默认实参...“虚函数”时才会发生,如果通过对象进行的函数调用,那么在编译阶段就确定该调用哪个版本的函数了(见下面的演示案例) 当然,如果派生类没有重写基类的虚函数,那么通过基类指针指向于派生类时,调用虚函数还是调用的基类的虚函数...方法是通过域运算符来实现 通常,只有成员函数(或友元)中的代码才需要使用作用域运算符来回避虚函数的机制 什么时候需要用到这种回避虚函数的机制: 通常,基类定义的虚函数要完成继承层次中所有的类都要完成的共同的任务
图5-3 重载成员函数 5.1.6 重载为友元函数 重载为友元函数时,没有隐含的参数this指针,即不改变原有运算符的语法结构 下列运算符不能重载为友元函数:=、()、[]、-> 重载为友元函数的运算符重载函数的格式...图5-4 重载友元函数 5.2 静态束定(静态联编) 静态联编是指联编工作在编译阶段完成的,这种联编过程是在程序运行之前完成的,又称为早期联编。...图5-9 纯虚函数 5.6 抽象类 带有纯虚函数的类称为抽象类 抽象类只能作为基类使用,其纯虚函数的实现由派生类给出;但派生类仍可不给出纯虚函数的定义,继续作为抽象类存在 抽象类不能定义对象,一般将该类的构造函数说明为保护的访问控制权限...在成员函数内可以调用纯虚函数,但在构造函数或析构函数内不能调用纯虚函数(纯虚函数没有实现代码) 5.6.1 抽象类的作用 1用作基类:在一个继承层次结构中,提供一个公共的根,并基于抽象类的操作设计出对抽象类所描述的一类对象进行操作的公共接口...,其完整的实现由派生类完成 2用作指针或引用的基类型:保证进入继承层次的每个类都具有(提供)纯虚函数所要求的行为 ?
而继承就体现了它用法,当为protected继承的时候,在派生类的里面是可以访问到基类的成员的。 大多数的情况下都是公共继承的,因为继承之后在派生类的外面是可以访问的。...要显示基类的类域才可以访问,没有显示类域默认访问派生类中的。 注意:只要名字一样就构成隐藏。...2.当基类没有默认的构造函数的时候,必须自己要写构造函数调用基类的 派生类的构造函数先初始化基类,再初始派生类中的成员 静态成员变量不属于具体的类对象,属于该类所有对象。...继承与友元 友元是不能继承的——基类友元不能访问派生类的私有和保护成员。...菱形继承与菱形虚拟继承 菱形继承 什么是菱形继承? 如下图:B继承了A,C也继承了A,D既继承了B也继承了C。这种继承关系就是菱形继承 为什么会出现菱形继承?
定制Attribute允许定义的信息应用于几乎每一个元数据表记录项,这种可扩展的元数据信息能在运行时查询,从而动态改变代码的执行方式。...attribute是类的一个实例,将一个attribute应用于一个目标元素时,语法类似于调用类的某个实例构造函数。...Inherited参数用于获取或设置一个布尔值,指示指定的属性是否可以继承由派生类和重写成员。 定制Attribute可以应用于单个目标元素,定制Attribute的顺序是无关紧要的。...三.友元程序集解析 扯了半天,终于到讲解“友元程序集”这一个概念,“友元程序集”在.NET2中提出,使用InternalsVisibleToAttribute来实现这一特性,InternalsVisibleTo...InternalsVisibleToAttribute继承自Attribute类,该类指定通常仅在当前程序集中可见的类型对指定程序集可见。该类包含两个属性和一个方法。
() { ; } 重载为类的友元函数,参数个数与原运算数个数一样多; friend operator () { ; } 函数重载...:父类的公有成员和保护成员作为子类的的私有成员,且不能被子类的派生类访问; 公有继承 public:父类的公有成员和保护成员作为子类的成员时,仍保持原有状态,父类私有成员仍为私有; 保护继承 protected...:父类的公有成员和保护成员成为子类的保护成员,且只能被他的派生类成员函数或友元访问,父类私有成员仍为私有; 派生类构造函数调用顺序: 调用基类的构造函数,调用顺序按继承时说明的顺序; 调用子对象类的构造函数...,不能是友元,但可以是另一个类的友元,不能为全局函数,也不能为静态函数,析构函数可以为虚函数,但构造函数不能为虚函数; 变量初始化 局部变量:定义时,系统不会进行初始化; 全局变量:定义时,系统自动初始化..., 友元函数 在类中定义过,但不是成员函数,定义在类外部,但有权访问类中成员; this 指针 只有成员函数才有 this指针,友元函数没有 this 指针; 静态成员函数与普通成员函数区别: 静态成员函数没有
领取专属 10元无门槛券
手把手带您无忧上云