派生类的子对象可以调用基类的函数吗
时间: 2023-12-02 14:06:04 浏览: 107
是的,派生类的对象可以调用基类的函数。派生类继承了基类的所有成员函数和成员变量,包括公有、保护和私有成员。在派生类中,可以通过使用基类的名字或者this指针来调用基类的函数。
例如,假设有一个基类Animal和一个派生类Dog,Dog类继承自Animal类。Animal类中有一个公有成员函数eat(),Dog类中也有一个公有成员函数bark()。在Dog类中,我们可以通过使用Animal::eat()来调用基类Animal的eat()函数,如下所示:
```c++
class Animal {
public:
void eat() {
cout << "Animal is eating." << endl;
}
};
class Dog : public Animal {
public:
void bark() {
cout << "Dog is barking." << endl;
Animal::eat(); // 调用基类Animal的eat()函数
}
};
```
在这个例子中,Dog类中的bark()函数通过使用Animal::eat()来调用基类Animal的eat()函数。当我们调用Dog类的bark()函数时,它会输出"Dog is barking."和"Animal is eating."。
相关问题
最派生类对象中虚基类表指针的应用代码实现
以下是一个示例代码,演示了如何使用虚基类和虚基类表指针:
```c++
#include <iostream>
using namespace std;
class Base {
public:
virtual void foo() {
cout << "Base::foo()" << endl;
}
};
class Derived1 : virtual public Base {
public:
virtual void foo() {
cout << "Derived1::foo()" << endl;
}
};
class Derived2 : virtual public Base {
public:
virtual void foo() {
cout << "Derived2::foo()" << endl;
}
};
class Final : public Derived1, public Derived2 {
public:
virtual void foo() {
cout << "Final::foo()" << endl;
}
};
int main() {
Final f;
Base* b = &f;
b->foo();
// 获取虚基类表指针
void* vbptr = (void*)&f;
Base* vbtable = *(Base**)vbptr;
// 访问虚基类子对象
vbtable->foo();
return 0;
}
```
在这个示例代码中,我们定义了一个虚基类 `Base`,和两个继承自 `Base` 的虚基类子类 `Derived1` 和 `Derived2`。然后,我们定义了一个最派生类 `Final`,它同时继承自 `Derived1` 和 `Derived2`,并且使用虚继承保证了虚基类 `Base` 的唯一性。
在 `main` 函数中,我们首先创建了一个 `Final` 类对象 `f`,然后将它的地址赋值给一个 `Base` 类型的指针 `b`,调用 `b->foo()` 方法。由于 `foo()` 方法是虚函数,因此会根据实际对象类型调用相应的版本,输出 `Final::foo()`。
接着,我们通过指针运算获取了 `f` 对象的地址,并将它转换为 `void*` 类型的指针 `vbptr`。然后,我们通过 `*(Base**)vbptr` 获取了虚基类表指针,将它赋值给 `Base*` 类型的指针 `vbtable`。
最后,我们通过 `vbtable->foo()` 方法访问了虚基类子对象的虚函数版本,输出 `Base::foo()`。这是因为虚基类 `Base` 在 `Final` 对象中只有一个实例,因此虚基类表中只存储了 `Base::foo()` 的地址,而不是 `Derived1::foo()` 或 `Derived2::foo()` 的地址。
设计一个简易魔兽世界游戏框架,定义表示人形类的抽象类 Humanoid 及其派生类,并实现多态操作,要求如下: (1)定义抽象类 Humanoid,添加公有成员函数 voidSayHello(),并将其定义为纯虚函数; (2)从 Humanoid 类公有派生矮人类 Dwarf,覆盖基类纯虚的数 void Say Hello(),实现输出 “"Hi, I am a dwarf"功能; (3)从 Humanoid 类公有派生精灵类 EIf覆盖基类纯虚的数 void Say Flello(),实现输出“Hi,I am an elf"功能. (4)从 Humanoid 类公有派生兽人类Orc,覆盖基类纯虚函数void Say Hello(),实现输出“Hi, I am an orc,"功能。 在main 主函数中,首先根据输入的整数创建相应大小的Humanoid 类类型指针数组,再根据输入的宇符动态创建相应派生类对象,并将其地址赋子基类类型指针数组元素。揄入信息格式如下: 3//要求创建 Humanoid 类对象指针数组的元素个数 D//根据字符D动态创建 Dwarf 类对象 E//根据字符E动态创建 EIf 类对象 O//根据字符O动态创建 Orc 类对象 通过 Humanoid 类对象指针数组的每个元素调用 SayHello 成员函数,实现多态。 输入描述: 对象指针数组长度 动态创建对象类型标记字符 输出描述: 依次输出 Humanoid 类对象指针数组的每一个元素调用 SayHello 函数的结果。
以下是简易魔兽世界游戏框架的代码实现:
```cpp
#include <iostream>
#include <vector>
using namespace std;
// 定义表示人形类的抽象类 Humanoid
class Humanoid {
public:
virtual void SayHello() = 0; // 纯虚函数
};
// 从 Humanoid 类公有派生矮人类 Dwarf
class Dwarf : public Humanoid {
public:
void SayHello() { // 覆盖基类纯虚函数
cout << "Hi, I am a dwarf" << endl;
}
};
// 从 Humanoid 类公有派生精灵类 Elf
class Elf : public Humanoid {
public:
void SayHello() { // 覆盖基类纯虚函数
cout << "Hi, I am an elf" << endl;
}
};
// 从 Humanoid 类公有派生兽人类 Orc
class Orc : public Humanoid {
public:
void SayHello() { // 覆盖基类纯虚函数
cout << "Hi, I am an orc" << endl;
}
};
int main() {
int n;
cin >> n; // 对象指针数组长度
vector<Humanoid*> arr(n); // 创建相应大小的 Humanoid 类类型指针数组
// 根据输入的字符动态创建相应派生类对象,并将其地址赋给基类类型指针数组元素
char ch;
for (int i = 0; i < n; i++) {
cin >> ch;
if (ch == 'D') {
arr[i] = new Dwarf();
} else if (ch == 'E') {
arr[i] = new Elf();
} else if (ch == 'O') {
arr[i] = new Orc();
}
}
// 通过基类类型指针数组的每个元素调用 SayHello 成员函数,实现多态
for (int i = 0; i < n; i++) {
arr[i]->SayHello();
}
// 释放动态分配的内存
for (int i = 0; i < n; i++) {
delete arr[i];
}
return 0;
}
```
输入示例:
```
3
D
E
O
```
输出示例:
```
Hi, I am a dwarf
Hi, I am an elf
Hi, I am an orc
```
阅读全文