c++的继承与多态

继承与多态

   继承的本质:代码的复用


1)派生类的内存布局,都继承了基类的什么。



2)继承来的东西的访问限定: 


3)派生类对象的构造顺序


4)派生类和基类同名成员方法的关系:

 重载:作用域相同,函数名相同,参数列表不同的函数。

 隐藏:继承结构中,派生类隐藏了与基类同名的函数。(隐藏基类,优先调用自己的)

 覆盖:基类有与派生类同名的函数,返回值相同,参数列表相同。并且基类的函数为虚函数。则基类的虚函数会覆盖派生类的函数。

5)基类对象和派生类对象能否互相赋值和引用

Base b;  Derive d;  

 基类对象---》派生类对象   例:d=b;  //error 因为派生类对象包含基类成员和派生类成员。会造成派生类的成员部分没有赋值

 派生类对象---》基类对象   例:b=d; //正确  因为派生类对象包含了基类成员的那部分,则可以赋值。     (编译器默认的支持自下向上的转换)

 基类对象的指针/引用----》派生类对象  :Base *pa=&d; //正确 但是指针接引用不能访问派生类的成员。因为指针的类型为Base*

 派生类对象的指针/引用----》基类对象   例:Derive *pb=&b;//error 


 6)虚函数和多态

 

 7)什么情况下产生多态的调用:使用指针和引用指向不同于该指针类型的对象的时候。

  

 8)纯虚函数和抽象类

 

  抽象类:拥有纯虚函数的类为抽象类,抽象类不能定义对象,可以定义指针/引用。







       

### C++ 中的继承多态机制 #### 1. 继承的概念 继承是面向对象编程的核心之一,它允许一个类(称为派生类或子类)从另一个类(称为基类或父类)获取属性行为。这种机制提高了代码的复用性扩展性[^1]。 在 C++ 中,可以通过 `class Derived : accessSpecifier Base` 的语法来定义继承关系,其中 `accessSpecifier` 可以是 `private`, `protected`, 或 `public`。不同的访问修饰符决定了派生类对外部世界暴露的程度以及对基类成员的访问权限[^2]。 #### 2. 多态的概念 多态是指同一个接口可以有多种实现形式的能力。C++ 支持两种类型的多态:编译时多态(静态多态运行时多态(动态多态)。运行时多态主要通过虚函数实现,而编译时多态通常由函数重载运算符重载提供[^3]。 ##### 运行时多态的关键要素 - **虚函数 (Virtual Function)**: 它是在基类中声明并可能被派生类覆盖的函数。当通过基类指针或引用调用虚函数时,实际执行的是派生类版本的函数。 - **纯虚函数**: 如果某个虚函数没有任何具体实现,则它可以被声明为纯虚函数 (`= 0`)。含有纯虚函数的类被称为抽象类,无法直接实例化。 #### 3. 示例代码展示继承多态 以下是一个完整的示例,说明如何利用继承多态: ```cpp #include <iostream> using namespace std; // 基类 Shape class Shape { public: virtual void draw() const = 0; // 纯虚函数 virtual ~Shape() {} // 虚析构函数确保正确清理资源 }; // 派生类 Circle class Circle : public Shape { public: void draw() const override { cout << "Drawing a circle." << endl; } }; // 派生类 Rectangle class Rectangle : public Shape { public: void draw() const override { cout << "Drawing a rectangle." << endl; } }; // 主函数演示多态 int main() { Shape* shapes[] = {new Circle(), new Rectangle()}; for(auto shape : shapes){ shape->draw(); // 动态绑定到具体的派生类方法 } // 清理分配的对象 for(auto& shape : shapes){ delete shape; } return 0; } ``` 在此示例中: - 创建了一个抽象基类 `Shape` 两个派生类 `Circle` `Rectangle`。 - 利用了虚函数 `draw()` 来体现多态行为。 - 当遍历 `shapes` 数组时,尽管所有的元素都被视为 `Shape*` 类型,但由于动态绑定的存在,实际上会调用各自派生类的具体实现。 #### 4. 关于模板中的继承多态 除了基本的数据类型外,还可以结合泛型编程技术——即模板,进一步增强灵活性。如下所示的例子展示了基于模板的继承结构及其多态特性[^4]: ```cpp template<typename T> class Test { public: Test(T x) : m_x(x) {} virtual void print() = 0; // 抽象方法 protected: T m_x; }; template<typename T> class Test2 : public Test<T> { public: Test2(T x, T y) : Test<T>(x), m_y(y) {} void print() override { cout << "x = " << this->m_x << ", y = " << m_y << endl; } private: T m_y; }; void testTemplate() { Test<int>* p = new Test2<int>(1, 3); p->print(); } int main(){ testTemplate(); return 0; } ``` 此案例强调了即使在涉及未知数据类型的情况下,仍然能保持良好的继承体系及支持多态操作的可能性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值