C++八股文之面向对象(二)——有哪些是访问修饰符? 什么是多重继承? 简述一下 C++ 的重载和重写,以及它们的区别

目录

有哪些访问修饰符?

什么是多重继承?

简述一下 C++ 的重载和重写,以及它们的区别


有哪些访问修饰符?

C++提供了三个访问修饰符: publicprivate protected 。这些修饰符决定了类中的成员对外部代码的可⻅性和访问权限。

public 修饰符⽤于指定类中的成员可以被类的外部代码访问。公有成员可以被类外部的任何代码(包括类的实例)访问。

private 修饰符⽤于指定类中的成员只能被类的内部代码访问。私有成员对外部代码是不可⻅的,只有类内部的成员函数可以访问私有成员。

protected 修饰符⽤于指定类中的成员可以被类的派⽣类访问。受保护成员对外部代码是不可⻅的,但可以在派⽣类中被访问。

什么是多重继承?

⼀个类可以从多个基类(⽗类)继承属性和⾏为。在C++等⽀持多重继承的语⾔中,⼀个派⽣类可以同时拥有多个基类。

多重继承可能引⼊⼀些问题,如菱形继承问题, ⽐如当⼀个类同时继承了两个拥有相同基类的类,⽽最终的派⽣类⼜同时继承了这两个类时,可能导致⼆义性和代码设计上的复杂性。为了解决这些问题,C++ 提供了虚继承, 通过 在继承声明中使⽤ virtual 关键字,可以避免在派⽣类中⽣成多个基类的实例,从⽽解决了菱形继承带来的⼆义性。

#include <iostream>
class Animal {
public:
    void eat() {
        std::cout << "Animal is eating." << std::endl;
    }
};
class Mammal : public Animal {
public:
    void breathe() {
        std::cout << "Mammal is breathing." << std::endl;
    }
};
class Bird : public Animal {
public:
    void fly() {
        std::cout << "Bird is flying." << std::endl;
    }
};
// 菱形继承,同时从 Mammal 和 Bird 继承
class Bat : public Mammal, public Bird {
public:
    void navigate() {
        // 这⾥可能会引起⼆义性,因为 Bat 继承了两个 Animal
        // navigate ⽅法中尝试调⽤ eat ⽅法,但不明确应该调⽤ Animal 的哪⼀个实现
        eat();
    }
};
int main() {
    Bat bat;
    bat.navigate();
    return 0;
}

#include <iostream>
class Animal {
public:
    void eat() {
        std::cout << "Animal is eating." << std::endl;
    }
};
class Mammal : virtual public Animal {
public:
    void breathe() {
        std::cout << "Mammal is breathing." << std::endl;
    }
};
class Bird : virtual public Animal {
public:
    void fly() {
        std::cout << "Bird is flying." << std::endl;
    }
};
class Bat : public Mammal, public Bird {
public:
    void navigate() {
        // 不再存在⼆义性,eat ⽅法来⾃于共享的 Animal 基类
        eat();
    }
};
int main() {
    Bat bat;
    bat.navigate();
    return 0;
}

简述一下 C++ 的重载和重写,以及它们的区别

1. 重载是指在同⼀作⽤域内,使⽤相同的函数名但具有不同的参数列表或类型,使得同⼀个函数名可以有多个版本。

int add(int a, int b)
{
    return a + b;
}

double add(double a, double b)
{
    return a + b;
}

2. 重写是指派⽣类(⼦类)重新实现(覆盖)基类(⽗类)中的虚函数,以提供特定于派⽣类的实现。重写是⾯向对象编程中的多态性的⼀种体现,主要涉及基类和派⽣类之间的关系,⽤于实现运⾏时多态。

class Base {
public:
    virtual void print() {
        cout << "Base class" << endl;
    }
}

// 重写
class Derived : public Base {
public:
    void print() override {
        cout << "Derived class" << endl;
    }
}

1、override是重写(覆盖)了⼀个⽅法

以实现不同的功能,⼀般是⽤于⼦类在继承⽗类时,重写⽗类⽅法。

规则:

  1. 重写⽅法的参数列表,返回值,所抛出的异常与被重写⽅法⼀致
  2. 被重写的⽅法不能为private
  3. 静态⽅法不能被重写为⾮静态的⽅法
  4. 重写⽅法的访问修饰符⼀定要⼤于被重写⽅法的访问修饰符(public>protected>default>private)

2、overload是重载,这些⽅法的名称相同⽽参数形式不同

⼀个⽅法有不同的版本,存在于⼀个类中。

规则:

  1. 不能通过访问权限、返回类型、抛出的异常进⾏重载
  2. 不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序(参数类型必须不⼀样)
  3. ⽅法的异常类型和数⽬不会对重载造成影响

使⽤多态是为了避免在⽗类⾥⼤量重载引起代码臃肿且难于维护。

重写与重载的本质区别是,加⼊了override的修饰符的⽅法,此⽅法始终只有⼀个被你使⽤的⽅法。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J^T

谢谢帅哥/美女

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值