通过基类的指针,我们无法访问派生类特定的成员

Through base class's pointer we can't access derived class specific members

本文关键字:派生 访问 成员 基类 指针 我们      更新时间:2023-10-16

基类指针可以指向派生类对象。为什么反之亦然?

该线程说我们不能使派生类指向基类,因为派生类可能无法访问基类的所有成员。

反之亦然。 基类甚至无法访问特定于派生类的成员。

#include <iostream>
using namespace std;
class BaseClass
{
public:
virtual void baseFx();
};
void BaseClass::baseFx()
{
std::cout << "From base virtual functionn";
}
class DerivedClass : public BaseClass
{
public:
void baseFx();
void h() { std::cout << "From derived class. h()n"; }
};
void DerivedClass::baseFx()
{
std::cout << "From derived virtual functionn";
}
int main()
{
BaseClass* objBaseclassB = new DerivedClass();
objBaseclassB->baseFx (); // Calls derived class's virtual function.
objBaseclassB->h(); // error: 'class BaseClass' has no member named 'h'.
return 0;
}

那么,为什么限制只针对派生类呢?考虑到上述逻辑,为什么不允许这样做?DerivedClass* objBaseclassC = new BaseClass();

将派生类对象分配给基类指针是有效的,并且是多态性的基石。

是的,派生类可能具有无法通过基类指针访问的其他成员,这没关系,因为程序员正在执行此类分配,同时完全知道无法访问这些成员。你这样做纯粹是为了多态性。这意味着您将只调用虚拟函数,这些函数将使用 vtables 根据指针指向的对象调用正确的覆盖。

但是,将基类指针转换回派生类指针并不简单。您需要类型信息,并且仅当基类是多态的(即具有虚函数)并且要强制转换为的类派生自基类时,才有可能。此确切检查由dynamic_cast执行。dynamic_cast检查是否可以进行向下转换,如果有效,则返回派生类指针。否则,它将返回nullptr.

来到最后一个问题:DerivedClass* objBaseclassC = new BaseClass();无效,因为访问 DerivedClass 中的任何"额外"成员都会导致崩溃。

但是当你这样做时BaseClass* derivedPointer = new DerivedClass();这样的构造将导致编译时错误。

让我尝试以合乎逻辑的方式解释这一点。

OO 编程中的继承用于实现不同类之间的"是"关系。例如。如果有一个类动物和一个类狗,我们知道狗"是"动物,因此狗会扩展动物。因此,它显然会表现出很多功能(例如 eat() - 函数),这在其他动物(类)中很常见,比如马。因此,我们倾向于将这样的公共代码放入基类 Animal 中,并在派生类中保留特定于每个子类的代码。(例如狗的吠叫()

因此,只有允许基类类型指针指向派生类对象才有意义,即 动物 * 马1 = 新马(); 毕竟马是动物。 反之亦然,因为每只动物不一定是马。

PS:就C++而言,继承主要只是通用代码的复用机制。