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

《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)「建议收藏」

从基类继承来的成员在派生类中的访问属性也有所不同。...在没有虚函数的情况下,如果在派生类中定义了与基类成员同名的成员,则称派生类成员覆盖了基类的同名成员,在派生类中使用这个名字意味着访问在派生类中声明的成员。...在C++中,可以通过将这个公共的基类声明为虚基类来解决这个问题。这就要求从类base派生新类时,使用关键字virtual将base声明为虚基类。...因此,抽象类只能作为其他类的基类来使用,不能建立抽象类对象。 不允许从具体类派生出抽象类。所谓具体类,就是不包含纯虚函数的普通类。 抽象类不能用作函数的参数类型、函数的返回类型或是显式转换的类型。...事实上,由于宏定义会造成不少麻烦,所以在C++中不主张使用宏定义。解决以上问题的另一个方法就是使用模板。

3.4K40

【笔记】《Effective C++》条款26-55

是唯一能做到这一点的新式转型符 dynamic_cast: 安全下转型(动态转型). 是运行时类型识别(RTTI)的一大工具, 可以将引用, 指针, 右值引用从基类转到派生类....: 接口与默认实现, 也就是类内=0但类外单独实现的纯虚函数, 允许派生类按照Base::interface来使用基类提供的默认实现 非虚函数: 接口与强制实现, 不希望派生类对这个接口进行改变 35..., 令用户只修改核心部分, 但利用总的接口来使用 NVI手法需要允许用户修改私有的虚函数, 这恰好是C++中"派生类可以重新定义继承来的私有虚函数, 因为继承而来的虚函数与基类无关"这个特性的应用 当派生类需要使用基类的一些内容时虚函数也会被写为..., 只和重载一样和名称与参数有关, 所以很容易二义 更复杂的情况是下图的"菱形继承": 菱形继承中, 对于不同基类都拥有的同名成员, C++默认会复制多份以供使用, 如果不希望复制就应该使用虚继承,...的双重意义 typename一般出现在模板参数中作为参数前缀, 在这种情况下typename和class是等价的(但是typename较晚推出, 建议使用语义更清晰的typename) 当一个模板中某个名称依赖于模板参数时

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

    C++ 继承

    继承概念及其定义 概念 C++继承是一种面向对象编程的特性,允许一个类(称为子类或派生类)继承另一个类(称为基类或父类)的属性和方法。..._b; A::operator=(x); } } int _b; }; 派生类型的析构函数会被调用玩后自动带哦用基类的析构函数清理基类成员,要保证先清理派生类型后清理基类...public A{}; class D:public A,public B{}; 一、节省内存空间 在多重继承中,如果不使用虚继承,一个基类可能会因为被不同的派生类从不同路径继承而导致其数据成员在派生类中存在多份拷贝...这种情况会造成内存空间的浪费。通过虚继承,可以确保无论基类被继承多少次,其数据成员在内存中只占用一份空间。这是因为虚继承机制使得所有从同一基类派生的类共享该基类的一个实例。...二、避免二义性问题 当派生类从多个路径继承同一个基类时,如果不使用虚继承,在派生类中访问基类成员时可能会产生二义性。

    4610

    后台开发:核心技术与应用实践 -- C++

    凡是函数体相同的函数都可以用这个模板来代替,而不用定义多个函数,实际使用时只需在模板中定义一次就可以了。在调用函数时,系统会根据实参的类型来取代模板中的虚拟类型,从而实现不同函数的功能。...面向对象的C++ 对象是类类型的一个变量,类则是对象的模板,类是抽象的,不占用存储空间的;而对象是具体的,占用存储空间。...而 虚函数 的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。...纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。...使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法来获取该实例。单例模式的作用就是保证在整个应用程序的生命周期中的任何时刻,单例类的实例都只存在一个(当然也可以不存在)。

    1.3K10

    十一、多态

    在C++中,多态主要通过虚函数来实现,并涉及以下三个关键要素: 继承关系 说明:多态必须发生在具有继承关系的类之间。即,一个类(子类或派生类)必须从另一个类(父类或基类)继承而来。...多态的意义 提高代码的复用性和可扩展性: 多态允许使用基类类型的指针或引用来引用派生类的对象,这样就可以通过基类指针或引用来调用派生类中的方法,而无需知道具体的派生类类型。...并且父类与子类中的函数必须有完全相同的原型 使用virtual声明之后能够产生多态(如果不使用virtual,那叫重定义) 多态是在运行期间根据具体对象的类型决定函数调用 虚函数 虚函数是基类中声明并在派生类中可以重写的函数...通过在基类中将函数声明为virtual,我们可以实现多态,即使用基类类型的指针或引用来调用派生类中的成员函数。...使用场景: 当你想通过基类指针或引用来调用派生类中的成员函数时。 实现多态性,即同一接口对应不同的实现。

    10110

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

    都能正常处理异常 异常对象的类型是由表达式的静态类型决定的,也就是我们抛出指向派生类的基类指针时,该派生类将被切去一部分 catch语句的括号内容是异常声明,类似函数的形参列表,用起来也很相近,和之前一样如果我们想要...学习标准库,类型不同的类放在各自的文件中,只要都放在同个命名空间中就好 要注意通常情况下我们不把#include放在命名空间内部,因为这代表我们要把头文件的所有名称都放入这个命名空间 当我们在命名空间中使用成员时可以直接使用名字...,这都可能引起混乱 18.3 多重继承与虚继承 C++支持多重继承(很多其他语言不支持这一特性),方法就是继承列表多些几个基类,因此我们可以从多个直接基类产生派生类,这个派生类会继承所有父类的属性...要注意的是基类的构造顺序是与派生列表中基类的出现顺序一致,与派生类参数顺序无关 C11中允许派生类从多个基类中继承构造函数,但是如果多个构造函数都相同的话将产生错误,此时派生类应该自己定义一个构造函数来覆盖它们...,虚基类是从最底层的派生类开始初始化的,也就是由最先一个虚派生汇合处的类开始初始化,此时即使这个类不是虚基类的直接派生也可以初始化虚基类的实例 而且编译器是先按顺序初始化所有的虚基类,然后再按顺序初始化非虚基类

    1K20

    继承机制深度解析:从基础到进阶的完整指南

    在C++中,可以对模板类进行继承。...模板类继承在泛型编程中非常有用,允许派生类在不同数据类型上复用模板基类的功能。这部分会涉及模板继承的具体语法和一些例子,以展示如何通过模板实现通用功能。...基类和派生类间的转换 在继承体系中,基类和派生类之间可以相互转换。尤其是在多态环境中,这种转换变得尤为重要。 在 C++ 中,基类和派生类之间的转换(类型转换)主要体现在指针和引用的转换。...这种转换需要谨慎,通常使用动态类型识别(如C++中的dynamic_cast)来确保类型安全。 2.1 向上转换(Upcasting) 向上转换是指将派生类的指针或引用转换为基类的指针或引用。...因为多态中⼀些场景析构函数需要构成重写,重写的条件之⼀是函数名相同那么编译器会对析构函数名进⾏特殊处理,处理成destructor(),所以基类析构函数不virtual的情况下,派生类析构函数和基类析构函数构成隐藏关系

    16810

    《逆袭进大厂》之C++篇49问49答(绝对的干货)

    所以将析构函数声明为虚函数是十分必要的。在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生,要将基类的析构函数声明为虚函数。...只有在基类析构函数定义为虚函数时,调用操作符delete销毁指向对象的基类指针时,才能准确调用派生类的析构函数(从该级向上按序调用虚函数),才能准确销毁数据。...重写关系中,调用方法根据对象类型决定,重载根据调用时实参表与形参表的对应关系来选择函数体 (3)隐藏(hide) 隐藏指的是某些情况下,派生类中的函数屏蔽了基类中的同名函数,包括以下情况: 两个函数参数相同...,如果对象类型是派生类,就调用派生类的函数,如果对象类型是基类,就调用基类的函数。...派生类对基类成员的访问形象有如下两种: 内部访问:由派生类中新增的成员函数对从基类继承来的成员的访问 外部访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问 (二)继承权限 public继承

    2.6K40

    《逆袭进大厂》之C++篇49问49答

    所以将析构函数声明为虚函数是十分必要的。在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生,要将基类的析构函数声明为虚函数。...只有在基类析构函数定义为虚函数时,调用操作符delete销毁指向对象的基类指针时,才能准确调用派生类的析构函数(从该级向上按序调用虚函数),才能准确销毁数据。...返回值不要求 重写关系中,调用方法根据对象类型决定,重载根据调用时实参表与形参表的对应关系来选择函数体 (3)隐藏(hide) 隐藏指的是某些情况下,派生类中的函数屏蔽了基类中的同名函数,包括以下情况:...,如果对象类型是派生类,就调用派生类的函数,如果对象类型是基类,就调用基类的函数。...派生类对基类成员的访问形象有如下两种: 内部访问:由派生类中新增的成员函数对从基类继承来的成员的访问 外部访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问 (二)继承权限 public继承

    2K10

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

    类型转换与多个基类 在只有一个基类的情况下,派生类的指针或者引用能自动转换成一个可访问基类的指针或者引用。...在多重继承的情况下,相同的查找过程在所有直接基类中同时进行,如果名字在多个基类中都被找到,则对该名字的使用将具有二义性。...当一个类具有多个基类时,有可能出现派生类从两个或者多个基类中继承了同名成员的情况。此时不加前缀限定符直接使用该名字将引发二义性。...虚继承 尽管在派生类列表中同一个基类只能出现一次,但实际上派生类可以多次继承同一个类: 派生类可以通过它的两个直接基类分别继承同一个间接基类 直接继承某个基类,然后通过另一个基类再一次间接继承该类 在默认情况下...当然,继承体系中的每个类都可能在某个时刻成为“最底层的派生类”。只要我们能创建虚基类的派生类对象,该派生类的构造函数就必须初始化它的虚基类。

    1.4K20

    浅析C++中的CRTP

    CRTP的基本思想:基类模板以派生类作为模板参数,在基类接口中将this指针强转为派生类指针,调用派生类中的方法,从而实现了一种静态多态性。...派生类Derived1和Derived2都继承自CBase,并实现了implementation方法。通过CRTP,我们可以在基类中调用派生类的方法,而不需要使用虚函数的运行时开销。...shared_from_this() 方法 objPtr->foo(); return 0; } 自定义类继承自模板类std::enable_shared_from_this,便可以在自定义类中使用模板类中的...回归CRTP,自定义类需要将自身作为模板参数传递给 std::enable_shared_from_this,在派生类中才可以使用 std::enable_shared_from_this 提供的 shared_from_this...实现策略模式:CRTP可以用于实现策略模式,将不同的策略封装在不同的派生类中,并在编译期确定使用哪种策略。

    6300

    封装、继承、多态、重载:C++中的强大特性与代码设计

    继承 C++中的继承是面向对象编程的一个重要概念,它允许一个类(派生类/子类)从另一个类(基类/父类)继承属性和行为。...C++中的继承有以下几种类型: 公有继承(public inheritance):派生类继承了基类的公有成员和保护成员,并且这些成员在派生类中的访问权限与基类中的一样。...旧类被称为基类或者父类,新类被称为派生类或者子类。 多态 C++中的多态是面向对象编程的一个重要概念,它允许使用指针或引用来处理不同类型的对象,而实际上执行的是根据对象类型动态选择的相关操作。...在main函数中,我们使用指向基类的指针shapePtr来处理不同类型的对象。...派生类中必须实现基类中的纯虚函数,否则被看做一个抽象类 对于一个没有任何接口的类,如果想要将它定义成抽象类,只能将虚构函数声明为纯虚的 通常情况下在基类中纯虚函数不需要实现,例外是纯析构函数要给出实现

    52010

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

    (3)使用抽象类时注意: 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类中没有重新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。...除非在派生类中完全实现基类中所有的的纯虚函数,否则,派生类也变成了抽象类,不能实例化对象。 二、纯虚函数引入原因 1、为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。...3、 基本数据类型 基本数据类型的转换以取值范围的作为转换基础(保证精度不丢失)。隐式转换发生在从小->大的转换中。比如从char转换为int。从int->long。...虚函数是为了实现动态编联产生的,目的是通过基类类型的指针指向不同对象时,自动调用相应的、和基类同名的函数(使用同一种调用形式,既能调用派生类又能调用基类的同名函数)。...在使用静态库的情况下,在编译链接可执行文件时,链接器从库 中复制这些函数和数据并把它们和应用程序的其它模块组合起来创建最终的可执行文件。

    2.2K30

    C++教程(最全)「建议收藏」

    14.3 虚基类 c++引入虚基类使得派生类再继承间接共同基类时只保留一份同名成员。 虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。...派生类对象赋值给基类对象、将派生类指针赋值给基类指针、将派生类引用赋值给基类引用 派生类对象赋值给基类对象,舍弃派生类新增的成员;派生类指针赋值给基类指针,没有拷贝对象的成员,也没有修改对象本身的数据,...、 上转型后通过基类的对象、指针、引用只能访问从基类继承过去的成员(包括成员变量和成员函数),不能访问派生类新增的成员 15.2 多态 不同的对象可以使用同一个函数名调用不同内容的函数。...15.3 虚函数 实现程序多态性的一个重要手段,使用基类对象指针访问派生类对象的同名函数。 将基类中的函数声明为虚函数,派生类中的同名函数自动为虚函数。...在模板引入 c++ 后,采用class来定义模板参数类型,后来为了避免 class 在声明类和模板的使用可能给人带来混淆,所以引入了 typename 这个关键字。

    2.5K30

    惯用法之CRTP

    其实,这样做的目的其实很明确,从基类对象的角度来看,派生类对象其实就是本身,这样的话只需要使用类型转换就可以把基类转化成派生类,从而实现基类对象对派生对象的访问。...截止到此,我们对CRTP有了一个初步的认识,总结起来,其有以下两个特点: • 继承自模板类 • 派生类将自身作为参数传给模板类 颠倒继承 仍然使用上一节中的例子,如下: template 派生类Derived中定义了一个成员函数imp(),而该函数在基类Base中是没有声明的,所以,我们可以理解为对于CRTP,在基类中调用派生类的成员函数,扩展了基类的功能。...而对于普通继承,则是派生类中调用基类的成员函数,扩展了派生类的功能,这就是我们所说的颠倒继承。 使用场景 俗话说,存在即合理。既然有CRTP,那么其必然有自己存在的道理。...但是,问题在于Base类实际上是一个模板类,而不是一个实际的类。因此,如果存在名为Derived和Derived1的派生类,则基类模板初始化将具有不同的类型。

    90220

    C++查缺补漏

    基类的private成员:不可直接访问 访问权限 派生类中的成员函数:可以直接访问基类中的public和protected成员,但不能直接访问基类的private成员 通过派生类的对象:不能直接访问从基类继承的任何成员...不需要显式地调用基类的析构函数,系统会自动隐式调用 先执行派生类析构函数的函数体,再调用基类的析构函数 访问从基类继承的成员 当派生类与基类中有相同成员时: 若未特别限定,则通过派生类对象使用的是派生类中的同名成员...如要通过派生类对象访问基类中被隐藏的同名成员,应使用基类名和作用域操作符(::)来限定 如果从不同基类继承了同名成员,但是在派生类中没有定义同名成员,“派生类对象名或引用名.成员名”、“派生类指针->...这时,派生类的虚函数便覆盖了基类的虚函数 派生类中的虚函数还会隐藏基类中同名函数的所有其它重载形式 一般习惯于在派生类的函数中也使用virtual关键字,以增加程序的可读性 虚析构函数 为什么需要虚析构函数...使用类模板使用户可以为类声明一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型(包括基本类型的和用户自定义类型) 类模板 template 模板参数表> class

    2.6K10

    C++教程(凯格尔训练法教程)

    14.3 虚基类 c++引入虚基类使得派生类再继承间接共同基类时只保留一份同名成员。 虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。...派生类对象赋值给基类对象、将派生类指针赋值给基类指针、将派生类引用赋值给基类引用 派生类对象赋值给基类对象,舍弃派生类新增的成员;派生类指针赋值给基类指针,没有拷贝对象的成员,也没有修改对象本身的数据,...、 上转型后通过基类的对象、指针、引用只能访问从基类继承过去的成员(包括成员变量和成员函数),不能访问派生类新增的成员 15.2 多态 不同的对象可以使用同一个函数名调用不同内容的函数。...15.3 虚函数 实现程序多态性的一个重要手段,使用基类对象指针访问派生类对象的同名函数。 将基类中的函数声明为虚函数,派生类中的同名函数自动为虚函数。...在模板引入 c++ 后,采用class来定义模板参数类型,后来为了避免 class 在声明类和模板的使用可能给人带来混淆,所以引入了 typename 这个关键字。

    2.9K20

    C++面试知识总结

    多态:通过继承同一个基类,产生了相关的不同的派生类,与基类中同名的成员函数在不同的派生类中会有不同的实现,也就是说:一个接口、多种方法。...函数覆盖是指派生类函数覆盖基类函数,函数名、参数类型、返回值类型一模一样。派生类的对象会调用子类中的覆盖版本,覆盖父类中的函数版本。 隐藏”是指派生类的函数屏蔽了与其同名的基类函数。...3.5 基类和子类的构造、析构顺序 定义一个对象时先调用基类的构造函数、然后调用派生类的构造函数 先派生类的析构后基类的析构,也就是说在基类的的析构调用的时候,派生类的信息已经全部销毁了 3.6 深拷贝与浅拷贝的区别...,派生类的成员函数可以访问基类中的公有和受保护成员;公有继承时基类受保护的成员,可以通过派生类对象访问但不能修改。...3.9 类成员中只能使用构造函数的初始化列表而不能赋值的有哪些 const成员 引用成员 3.10 函数模板与类模板的区别 函数模板是模板的一种,可以生成各种类型的函数实例,函数模板的实例化是由编译程序在处理函数调用时自动完成的

    1.8K41

    【笔记】《Effective C++》条款1-25

    C++11后加入了=delete操作, 让我们可以明确删除某些函数的生成 7 为多态基类声明virtual析构函数 对所有多态基类来说, 声明虚析构函数非常重要, 这是因为派生类如果被基类指针指着, 然后被..., 是先构造基类, 然后逐级向上构造的, 底层构造完成前, 派生类的相关变量都是未定义的....因此如果在构造函数中调用了虚函数, 那么会根据当前正在构造的类型来调用相应的虚函数版本, 而非派生类的版本...., 同时在日常中通过重载调用运算来模拟指针方便开发 隐式类型转换可以写, 比较自然, 但是有时有危险 更常见的情景是写一个显式的get函数来获取原始指针 牢记RAII类不是为了封装数据存在的, 而是为了给原始指针加上资源回收的功能..., 也就是由拷贝构造函数生成 因此如果只是简单地传入对象会浪费很多的构造/析构操作, 最好的做法是传const引用 传const是为了让调用的人放心传入, 同时传入引用还能避免对象切割问题(派生类传入声明为基类的参数时派生类会退化为基类

    1.1K30

    【C++】继承

    (对于派生类增加的成员,基类对象中也没有值可以赋) • 基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。...此外,在赋值过程当中虽然基类与派生类的类型不同,但是这里并没有发生类型转换产生临时对象,可以理解为编译器对切片这一操作特殊处理了。 3. 继承中的作用域 3.1 隐藏规则: 1....(在派生类成员函数中,可以使用 基类::基类成员 显示访问) 3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。 4....派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员(在之前类文章中,我们了解到编译器默认生成的函数,对于内置类型的行为是不确定的,对于自定义类型是调用它的默认函数。...注:一般情况下,如果我们的程序不涉及深拷贝,如果父类有对应的默认函数,那么我们仅使用编译器默认生成的就可以了,相关继承的父类成员,编译器会自动调用父类成员的默认函数进行处理。

    6100
    领券