首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++继承

在封装的过程中,我们发现有很多地方有问题,比如我们在封装Windows API 的过程中,每个窗口都有各自的消息处理,而我们封装时不同的窗口要针对不同的消息而编写不同的消息处理函数,不可能所有窗口对于某些消息都进行相同的处理...,而后面的部分保存的是派生类的内容,这样派生类就可以拥有基类的所有成员,而不必重写代码达到了代码重用的目的。...在设计中一般将类的共性提取出来作为基类,而将不同的部分从基类派生,作为每个类的特性,对于共性的内容我们只需要在基类中编写,而在派生类中直接使用。...: 通过这个表我们可以总结出一下几点: 1)私有成员在任何情况下都不能被派生类访问; 2)公有继承下其他基类成员在派生类中的访问属性不变; 3)私有继承下其他基类成员在派生类中全部变为私有; 4)保护继承下其他类成员在派生类中全部变为保护属性...; 从这个表中我们可以看出,私有继承与保护继承对于基类的访问属性完全相同,那么它们有何区别呢?

60520

【笔记】《C++Primer》—— 第18章:用于大型程序的工具

,此时编译器将负责保证其中的对象的销毁,此时这些对象的析构函数会自动调用 但是异常可能在任何地方出现,即使在析构函数中也是一样,为了保证析构的正常我们需要自己保证析构时不应该抛出自己无法处理的异常到外层...要注意是构造函数开始执行后的异常,如果是参数初始化过程中发生的异常则需要调用者自己在上下文中处理 异常发生时抛出的异常对象是一种特殊的对象,可以是类对象也可以是函数或数组指针。...,不用特指,和模板内部调用成员类似 我们也可以在命名空间的外部定义命名空间内的成员,但是注意只能是在外层,不能在不相干的同级作用域中定义 全局作用域实际上是一个无名命名空间,我们用::XXX来特指 C11...,如果我们直接调用函数传递派生类对象进去,会产生二义性错误,需要用特质来解决 和单继承时一样,静态类型决定了我们能调用那些成员 在多继承的时候,名称查找会在所有直接基类中同时进行,单个继承链上才有顺序,...此时如果名字在多个基类中被同时找到,则名字会有二义性,因此最好我们调用基类函数时也要特指 和之前一样,先找名字再类型检查,因此名字相同就已经会发生二义性错误了 尽管派生类中直接基类只能出现一次,但显然我们可以间接继承多次相同的基类

1K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【喂到嘴边了的模块】OOPC开发从未如此简单

    我们并没有为这项特性牺牲任何代码空间。 例子工程可以帮助我们快速的熟悉 OOC 的开发模式,那么在任意的普通工程中,我们要如何使用 PLOOC模板呢?...模板,分别对应: 基类和普通类(Base Class Template) 派生类(Derived Class Template) 由于我们要创建的是一个普通类(未来也可以作为基类),因此选择“Base...但你仔细思考一下,在类的结构体中加入函数指针究竟有何利弊: 先来说好处: 可以用“优雅”的方式来完成方法的调用; 支持运行时刻的重载(Override); 再来说缺点: 在嵌入式应用中,大部分类的方法都不需要重载...以后,在任何地方,都可以通过 类名大写>.() 的形式来访问类的操作函数了——这也算某种程度上的优雅了吧。...第六步:如何设计派生类(Derived Class) 派生类的创建在基本步骤上与普通类基本一致,除了在模板选择阶段使用对应的模板外,还需要在“格式化”阶段额外添加以下两个替换步骤: 将 <BASE_CLASS_NAME

    1.7K30

    【C++】模板继承多态

    模板代码是不能在一个文件中定义,在另一个文件中使用 模板代码调用之前,一定要看到模板定义的地方,这样的话,模板才能进行正常的实例化,产生能够被编译器编译的代码。...模板一般都是放在头文件中的,在源文件中展开 函数模板的非类型参数 必须是整数类型(整数/地址/引用)都是常量,只能使用 继承 继承的本质和原理 继承·的·本质·: a.代码复用 b.在基类中给所有派生类提供统一的虚函数接口...类型从下到上的转换(可以) 派生类指针(引用)基类对象 类型从上到下的转换(不可以) 在继承结构中进行上下的类型转换,默认只支持从下到上的类型转换。...在声明虚基类时,需要在派生类的继承列表中使用关键字 virtual。这样做可以确保每个派生类只包含一份虚基类的实例,从而避免了数据重复和二义性。...通过使用 dynamic_cast 将 basePtr 转换为 Derived* 类型的指针 derivedPtr,我们可以安全地调用 Derived 类的方法。

    10510

    《逆袭进大厂》第三弹之C++提高篇79问79答

    (3)使用抽象类时注意: 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。...如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它是一个可以建立对象的具体的类。 抽象类是不能定义对象的。一个纯虚函数不需要(但是可以)被定义。...除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。 二、纯虚函数引入原因 1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。...2) 多重继承的优点很明显,就是对象可以调用多个基类中的接口; 3) 如果派生类所继承的多个基类有相同的基类,而派生类对象需要调用这个祖先类的接口方法,就会容易出现二义性 4) 加上全局符确定调用哪一份拷贝...所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。 140、在成员函数中调用delete this会出现什么问题?对象还可以使用吗?

    2.2K30

    【C++】继承

    面向对象的程序设计中,如果我们想要模拟实现这种一个人的不同身份,并存储对应信息,难道实现“人”、“学生”、“工人”这些模板时,我们每个模板中都有名称、年龄、性别这些信息吗?...基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。 3....实际上面的表格我们进行一下总结会发现,基类的私有成员在派生类都是不可见。...(在派生类成员函数中,可以使用 基类::基类成员 显示访问) 3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。 4....对于子类与父类都是模板的情况,需要注意的是像构造、析构等函数,编译器默认生成时,在汇编层面实际上会自动调用,所以相关的父类函数会实例化,因此即使我们没有显式调用也不会报错。

    6100

    C++面试知识总结

    在实际编程中不需要了解在我们的系统上空指针到底是一个 0指针还是非0地址,我们只需要了解一个指针是否是空指针就可以了——编译器会自动实现其中的转换,为我们屏蔽其中的实现细节。...多态:通过继承同一个基类,产生了相关的不同的派生类,与基类中同名的成员函数在不同的派生类中会有不同的实现,也就是说:一个接口、多种方法。...3.5 基类和子类的构造、析构顺序 定义一个对象时先调用基类的构造函数、然后调用派生类的构造函数 先派生类的析构后基类的析构,也就是说在基类的的析构调用的时候,派生类的信息已经全部销毁了 3.6 深拷贝与浅拷贝的区别...,派生类的成员函数可以访问基类中的公有和受保护成员;公有继承时基类受保护的成员,可以通过派生类对象访问但不能修改。...3.9 类成员中只能使用构造函数的初始化列表而不能赋值的有哪些 const成员 引用成员 3.10 函数模板与类模板的区别 函数模板是模板的一种,可以生成各种类型的函数实例,函数模板的实例化是由编译程序在处理函数调用时自动完成的

    1.8K41

    C++系列笔记(五)

    【导读】《21天学通C++》这本书通过大量精小短悍的程序详细而全面的阐述了C++的基本概念和技术,包括管理输入/输出、循环和数组、面向对象编程、模板、使用标准模板库以及创建C++应用程序等...为什么需要虚构函数 上面的代码如果加入析构函数释放内存,对于使用new在自由储存区中实例化的派生类对象,如果将其赋值给基类指针,并通过该指针调用delete,将不会调用派生类的析构函数,这可能导致资源未释放...这让基类可指定派生类中方法的名称和特征(Signature),即指定派生类的接口。虽然不能实例化抽象基类,但可将指针或引用的类型指定为抽象基类。...注意:C++关键字virtual的含义随上下文而异(我想这样做的目的很可能是为了省事),对其含义总结如下: 在函数声明中,virtual意味着当基类指针指向派生对象时,通过它可调用派生类的相应函数。...可将复制构造函数声明为虚函数吗 根本不可能实现虚复制构造函数,因为在基类方法声明中使用关键字virtual时,表示它将被派生类的实现覆盖,这种多态行为是在运行阶段实现的。

    68930

    《C++Primer》第十八章 用于大型程序的工具

    与其他函数调用一样,如果在参数初始化的过程中发生了异常,则该异常属于调用表达式的一部分,并将在调用者所在的上下文中处理。 处理构造函数初始值异常的唯一方法是将构造函数写成函数try语句块。...1.2 模板特例化 模板特例化必须定义在原始模板所属的命名空间中,和其他命名空间名字类似,只要我们在命名空间中声明了特例化,就能在命名空间外部定义它了: // 我们必须将模板特例化声明成std的成员 namespace...std { template struct hash; } // 在std中添加了模板特例化的声明后,我们就可以在命名空间std的外部定义它了 template派生类使用的是合成版本的拷贝、移动或赋值成员时,才会自动对其基类部分执行这些操作。在合成的拷贝控制成员中,每个基类分别使用自己对应成员隐式地完成构造、赋值或销毁等工作。...虚继承 尽管在派生类列表中同一个基类只能出现一次,但实际上派生类可以多次继承同一个类: 派生类可以通过它的两个直接基类分别继承同一个间接基类 直接继承某个基类,然后通过另一个基类再一次间接继承该类 在默认情况下

    1.4K20

    惯用法之CRTP

    其实,这样做的目的其实很明确,从基类对象的角度来看,派生类对象其实就是本身,这样的话只需要使用类型转换就可以把基类转化成派生类,从而实现基类对象对派生对象的访问。...截止到此,我们对CRTP有了一个初步的认识,总结起来,其有以下两个特点: • 继承自模板类 • 派生类将自身作为参数传给模板类 颠倒继承 仍然使用上一节中的例子,如下: template 在基类Base中是没有声明的,所以,我们可以理解为对于CRTP,在基类中调用派生类的成员函数,扩展了基类的功能。...而对于普通继承,则是派生类中调用基类的成员函数,扩展了派生类的功能,这就是我们所说的颠倒继承。 使用场景 俗话说,存在即合理。既然有CRTP,那么其必然有自己存在的道理。...结语 通过CRTP技术,在某种程度上也可以实现多态功能,但其也仅限定于使用场景,正如局限性一节中所提到的,CRTP是一种特殊类型的多态性,在少数情况下可以替代动态多态性的需要;另外,使用CRTP技术,代码可读性降低

    90420

    【笔记】《C++Primer》—— 第三部分:类设计者的工具

    ,如果需要拷贝操作时,最好定义好所有其他操作 有时我们不希望用户使用一些函数,可以在函数名后加=delete表示删除(操作与=default一样),此时也不需要函数体,可以对任意函数标记,但要注意一定要在函数第一次声明的地方就标记...,派生类一般在构造函数开始的地方调用基类的构造函数,让基类来初始化自己的成员 静态类型是变量本身代码中的类型,在编译时决定,动态类型是变量在内存中的对象的类型,在运行时才能决定。...基类中此成员的访问说明符,这是最重要的一部分 派生类的派生列表的访问说明符,这一项决定的是派生类对继承来的成员对外表现出的最高权限 有时候我们需要改变外部对派生类继承的某个名字的访问级别,可以在自己的访问控制符处用...,对于实现的内容我们一样可以使用=default简化 如果基类中的基本操作函数不可访问或被删除,则派生类中的对应成员是被删除的因为我们无法使用基类来操作那些成员 C11中,我们可以用using重用基类定义的构造函数...类模板不会推断参数的类型 类模板的成员函数只有在使用时才会实例化 类模板与另一个模板直接最常见的友元是一对一的友元,首先模板需要声明所有需要用到的名字,然后在声明友元时标注出目标类的具体模板实参 类模板也可以一对多友元

    1.7K10

    互联网几道常考易错笔试题总结

    转载于http://blog.csdn.net/chhuach2005/article/details/40322895 1)  覆盖 重载 隐藏 覆盖:基类定义的虚函数,派生类中重新定义,派生类的虚函数表将覆盖基类已定义的虚函数...隐藏发生在派生类中有何基类同名的虚函数时,此时基类中的同名重载函数不被继承到派生类。...,用指针可以调用,隐藏和多态同时出现时,隐藏优先级高     p->fun1(3.3);//由于隐藏优先级高,此处用基类指针调用fun1(3.3),不会发生多态,调用的是基类的fun1(3.3),在基类又会产生重载...p->fun1(3);  //多态调用派生类中的函数     p->fun1();   //同理会调用基类的fun1()函数,在基类会有重载。     ...执行结果为图2,从图2中可以看出,是先构造类的全局变量的,哪怕它在main函数之后,在main函数里的类变量构造是按类变量的定义顺序构造的。 ?

    37020

    第 18 章 用于大型程序的工具

    ,不过该异常属于调用表达式的一部分,将在调用者所在的上下文中进行处理。...// 我们必须将模板特例化声明成std的成员 namespace std { template struct hash; } // 在std中添加了模板特例化的声明后,就可以在命名空间...自定义的拷贝/赋值构造函数和赋值运算符都需要显式调用基类的相应成员来完成派生类对象的拷贝、移动和赋值操作。只有当派生类使用的是合成版本的函数时,才会自动对齐基类部分执行相应操作。...这在某些情形会出现问题,使用虚继承机制可以解决上述问题,在这种机制下,不论虚继承在继承体系中出现了多少次,在派生类中都只包含唯一一个共享的虚基类子对象。...此外,如果虚基类的成员只被一条派生路径覆盖,则我们仍然可以直接访问这个被覆盖的成员。但是如果成员被多于一个基类覆盖,则一般情况下派生类必须为该成员自定义一个新的版本。

    93020

    .NET面向上下文、AOP架构模式(实现)

    由于多线程应用框架的入口点不是我们所能控制的,所以在使用上下文模式的时候需要使用线程本地存储解决线程不安全访问的问题。.../// 使用该特性的类将是上下文活跃的,只有在使用的时候才确定当前上下文。...在抽象类中约定行为,在派生类中实现具体。 这里比较有意思的是,特性不在像大家实现ORM的那中简单的标识了。其实特性真正强大的地方在于运行时能动态的获取到,这得益于.NET元数据的功劳。.../// 上下文中的任何方法如果需要进行上下文管理的,则使用ContextModule.ContextOperationBaseAttribute特性派生类进行管理。.../// 对上下文发起的方法调用需要通过该基类进行调用才能让我们的扩展点使用成为可能。

    70920

    C++多态特性

    它可以通过两种方式实现: (1)虚函数(virtual function) 虚函数是在基类中声明的函数,它可以被派生类重写,实现多态的效果。...在派生类中实现的函数可以覆盖基类中的同名函数,而且会在运行时的对象类型上调用合适的函数。通过将基类指针或引用指向派生类对象,可以实现动态多态性。 (2)模板(template)。...(前面已经讲过了) 模板是一种通用的代码库,可以为不同的类型提供相同的代码实现。使用模板可以实现静态多态性。在编译期间,编译器会依据模板中使用的类型,生成适当的代码。...你需要支付10元的午餐费! 你需要支付10元的午餐费! 在前面的继承章节,我们知道,基类和派生类是两个不同的作用域,定义同名的两个函数时,会形成隐藏操作.所以这里的打印结果都是一样的....已扣除5元餐费." << endl; return nullptr; } }; 运行结果: 2.1 析构函数可以是虚函数吗? 显然,基类与派生类析构函数的名字不同 .

    14370

    第 18 章 用于大型程序的工具

    ,不过该异常属于调用表达式的一部分,将在调用者所在的上下文中进行处理。...// 我们必须将模板特例化声明成std的成员 namespace std { template struct hash; } // 在std中添加了模板特例化的声明后,就可以在命名空间...自定义的拷贝/赋值构造函数和赋值运算符都需要显式调用基类的相应成员来完成派生类对象的拷贝、移动和赋值操作。只有当派生类使用的是合成版本的函数时,才会自动对齐基类部分执行相应操作。...这在某些情形会出现问题,使用虚继承机制可以解决上述问题,在这种机制下,不论虚继承在继承体系中出现了多少次,在派生类中都只包含唯一一个共享的虚基类子对象。...此外,如果虚基类的成员只被一条派生路径覆盖,则我们仍然可以直接访问这个被覆盖的成员。但是如果成员被多于一个基类覆盖,则一般情况下派生类必须为该成员自定义一个新的版本。

    99450

    【C++】多态

    之前的文章我们学习了C++的继承,这篇文章我们来学习多态 前言 需要声明的,本文中的代码及解释都是在vs2022下的x86程序中,涉及的指针都是4bytes。...注意⚠: 在重写基类虚函数时,派生类的虚函数不加virtual关键字,也可以构成重写(可以认为继承后基类的虚函数被继承下来了在派生类中依旧保持虚函数属性),但是该种写法不是很规范,不建议这样使用 但是父类的...但是在这个地方,我们期望它是这样正常的只调父类的析构吗? 是不是不期望啊,因为如果父类的指针指向的是子类对象,在delete的时候还是只调父类的析构,那是不是就可能会有内存泄漏的风险啊。...因此结果是B->0 那说到这里我们也顺便来区分一组概念: 4. 接口继承和实现继承 普通函数的继承是一种实现继承,派生类继承了基类的成员函数,可以使用该函数,继承的是函数的实现。...这样,无论我们有一只狗还是一只猫,我们都可以使用"动物"类的指针或引用来调用"发出声音"方法,而不需要关心具体是哪种动物。

    12410

    聊下继承与多态的区别?

    看文章之前,别忘了关注我们,在我们这里,有你所需要的干货哦! ---- 1.基础概念 (1)继承 指可以让某个类型的对象,获得另一种类型对象属性的方法。...private:私有继承 基类private成员 不能继承 基类public、protected成员,可以继承,在派生类中需要通过private访问 protected:保护继承: 基类private...成员 不能继承 基类public成员,可以继承,在派生类中相当于是protected访问 基类protected成员,可以继承,在派生类中相当于是protected访问 public:公有继承:...基类private成员 不能继承 基类public成员,可以继承,在派生类中相当于是public访问 基类protected成员,可以继承,在派生类中相当于是protected访问 派生方式 基类的public...总结 在面向对象过程中,通常我们会以多个对象共有的特性作为基类进行创建。然后利用继承的特性,对基类进行派生。 基类与派生类存在相同的方法,但是有不同的方法体。

    5.8K20

    C++primer学习笔记(六)

    可以使用域操作符强制调用基类虚函数【虚中调虚】。基类虚函数和派生类的默认实参要一致。...派生类继承基类的访问控制标号【何种方式继承】无论是什么,不影响派生类使用基类成员,但影响使用派生类的用户访问基类成员。类使用接口继承还是实现继承对派生类用户具有重要含义。 友元关系不继承。...如果知道基类到派生类的转换【这种转换是基类地址赋给派生类指针】是安全的【就是说心里清楚基类指针指向的确实是派生类】,可以使用static_cast强制编译器进行转换。...构造函数是对象动态类型确定之前运行的,不需要定义为virtual。 引用、对象、指针的静态类型决定了能够完成的行为,动态类型有多的功能也无法使用。派生类应避免与基类成员名字冲突。...表中可以有非类型形参,实例化时绑定值。 通过在成员前面加上typename告诉编译器将成员当做类型。

    1.1K20
    领券