MST

星途 面试题库

面试题:C++ 中继承与多态的基础理解

请解释 C++ 中 public、protected 和 private 继承方式的区别,并举例说明在多态场景下,不同继承方式对基类和派生类成员访问的影响。
46.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

继承方式区别

  1. public继承
    • 基类的public成员在派生类中仍是public成员,protected成员在派生类中仍是protected成员,private成员在派生类中不可访问。
    • 这意味着可以通过派生类对象访问基类的public成员,而只能在派生类内部访问基类的protected成员。
  2. protected继承
    • 基类的public和protected成员在派生类中都变成protected成员,private成员在派生类中不可访问。
    • 此时,只有派生类及其派生类(如果有)内部可以访问基类的这些成员,外部通过派生类对象无法访问。
  3. private继承
    • 基类的public、protected成员在派生类中都变成private成员,private成员在派生类中不可访问。
    • 这样,基类的成员只能在派生类内部访问,派生类的派生类也无法访问从基类继承来的这些成员。

多态场景下的影响示例

#include <iostream>

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

// public继承
class PublicDerived : public Base {
public:
    void print() override {
        std::cout << "PublicDerived::print" << std::endl;
    }
};

// protected继承
class ProtectedDerived : protected Base {
public:
    void print() override {
        std::cout << "ProtectedDerived::print" << std::endl;
    }
};

// private继承
class PrivateDerived : private Base {
public:
    void print() override {
        std::cout << "PrivateDerived::print" << std::endl;
    }
};

void callPrint(Base* ptr) {
    ptr->print();
}

int main() {
    PublicDerived publicObj;
    ProtectedDerived protectedObj;
    PrivateDerived privateObj;

    Base* publicPtr = &publicObj;
    // Base* protectedPtr = &protectedObj; 错误,ProtectedDerived以protected继承Base,不能隐式转换为Base*
    // Base* privatePtr = &privateObj; 错误,PrivateDerived以private继承Base,不能隐式转换为Base*

    callPrint(publicPtr);
    // callPrint(&protectedObj); 错误,不能隐式转换
    // callPrint(&privateObj); 错误,不能隐式转换

    return 0;
}

在上述代码中:

  • public继承PublicDerived以public继承BasePublicDerived对象可以隐式转换为Base指针,在多态场景下(如callPrint函数)可以正常使用。
  • protected继承ProtectedDerived以protected继承Base,不能将ProtectedDerived对象隐式转换为Base指针,在多态场景下不能传递ProtectedDerived对象指针给期望Base指针的函数。
  • private继承PrivateDerived以private继承Base,同样不能将PrivateDerived对象隐式转换为Base指针,无法在多态场景下按基类指针的方式使用。