派生类和基类之间有一些特殊关系。
1)如果继承方式是公有的,派生类对象可以使用基类成员。
2)可以把派生类对象赋值给基类对象(包括私有成员),但是,会舍弃非基类的成员。
3)基类指针可以在不进行显式转换的情况下指向派生类对象。
4)基类引用可以在不进行显式转换的情况下引用派生类对象。
注意:
1)基类指针或引用只能调用基类的方法,不能调用派生类的方法。
2)可以用派生类构造基类。
3)如果函数的形参是基类,实参可以用派生类。
4)C++要求指针和引用类型与赋给的类型匹配,这一规则对继承来说是例外。但是,这种例外只是单向的,不可以将基类对象和地址赋给派生类引用和指针(没有价值,没有讨论的必要)。
下面是一个C++示例代码,演示了派生类和基类之间的特殊关系:
#include <iostream>
class Base {
public:
int baseValue;
void showBase() {
std::cout << "Base::showBase() - baseValue: " << baseValue << std::endl;
}
};
class Derived : public Base {
public:
int derivedValue;
void showDerived() {
std::cout << "Derived::showDerived() - derivedValue: " << derivedValue << std::endl;
}
};
void demonstrate(Base obj) {
obj.showBase();
}
int main() {
Derived d;
d.baseValue = 10;
d.derivedValue = 20;
// 1. 派生类对象可以使用基类成员
d.showBase();
d.showDerived();
// 2. 把派生类对象赋值给基类对象
Base b = d; // 会舍弃派生类的成员
b.showBase();
// b.showDerived(); // 错误,基类对象不能调用派生类的方法
// 3. 基类指针指向派生类对象
Base* basePtr = &d;
basePtr->showBase();
// basePtr->showDerived(); // 错误,基类指针不能调用派生类的方法
// 4. 基类引用引用派生类对象
Base& baseRef = d;
baseRef.showBase();
// baseRef.showDerived(); // 错误,基类引用不能调用派生类的方法
// 5. 用派生类对象作为实参调用基类形参的函数
demonstrate(d);
return 0;
}
解释:
- 派生类对象可以使用基类成员(如
d.showBase()
)。 - 把派生类对象赋值给基类对象时,会舍弃派生类的成员,只保留基类的成员。
- 基类指针可以指向派生类对象,但只能调用基类的方法,不能调用派生类的方法。
- 基类引用可以引用派生类对象,但也只能调用基类的方法。
- 可以用派生类对象作为实参调用形参为基类的函数。