多继承中用虚基类的目的?什么是最派生类?
时间: 2024-01-11 14:02:41 浏览: 144
用虚基类的目的是避免在多继承中出现“菱形继承”(Diamond Inheritance)问题,即同一个基类被间接继承多次,导致派生类中出现多份相同的基类成员,从而引发二义性和不必要的内存浪费。
虚基类是指在多继承中,被继承的基类使用了虚继承。虚继承是通过在继承关系中指定虚继承关键字“virtual”来实现的。当一个派生类继承了一个虚基类,它就共享了虚基类的一个唯一实例,而不是像普通继承那样继承了基类的一个独立实例。
最派生类指的是多继承中最终派生出来的类,它没有被其他类继承。在多继承中,最派生类继承了所有的基类和虚基类。最派生类中的成员变量和成员函数包括它自己定义的和从基类和虚基类中继承的。在使用多继承时,我们通常需要在最派生类中实现所有的接口和逻辑,以确保程序的正确性和可读性。
相关问题
写一个C++程序, 声明一个基类BaseClass,有整型成员变量Number,构造其派生类DerivedClass,观察构造函数和析构函数的执行情况编写程序声明一个基类BaseClass,构造其派生类DerivedClass,在构造函数和析构函数中用cout输出提示信息,观察构造函数和析构函数的执行情况。
好的,以下是程序的实现:
```c++
#include <iostream>
using namespace std;
class BaseClass {
public:
int Number;
BaseClass() {
cout << "BaseClass constructor called" << endl;
}
~BaseClass() {
cout << "BaseClass destructor called" << endl;
}
};
class DerivedClass : public BaseClass {
public:
DerivedClass() {
cout << "DerivedClass constructor called" << endl;
}
~DerivedClass() {
cout << "DerivedClass destructor called" << endl;
}
};
int main() {
DerivedClass d;
return 0;
}
```
程序中,首先定义了一个基类`BaseClass`,其中有一个整型成员变量`Number`,并在构造函数和析构函数中分别输出提示信息。然后定义了一个派生类`DerivedClass`,继承自`BaseClass`,并在构造函数和析构函数中分别输出提示信息。最后在`main`函数中创建一个`DerivedClass`对象`d`,观察构造函数和析构函数的执行情况。
运行程序后,输出结果如下:
```
BaseClass constructor called
DerivedClass constructor called
DerivedClass destructor called
BaseClass destructor called
```
从输出结果可以看出,对象创建时先执行基类的构造函数,再执行派生类的构造函数;对象销毁时先执行派生类的析构函数,再执行基类的析构函数。这就是多态性的体现,派生类对象包含了基类对象,因此在创建和销毁对象时都要先执行基类的构造函数和析构函数。
3. (论述题) 有以下程序结构,分析访问属性,请在下面窗口中填写答案。 #include <iostream> using namespace std; class A {public: void f1( ); protected: void f2(); private: int i; }; class B: public A {public: void f3( ); int k; private: int m; }; class C: protected B {public: void f4(); protected: int n; private: int p; }; class D: private C {public: void f5(); protected: int q; private: int r; }; int main() {A a1; B b1; C c1; D d1; return 0; } (1)在main函数中能否b1.i,b1.k和b1.m引用派生类B对象b1中的成员? (2)在main函数中能否d1.i,d1.k, d1.m,d1.n,d1.p,d1.q,d1.r引用派生类D对象d1中的成员? (3)派生类B中的成员函数能否调用基类A中的成员函数f1和f2? (4)派生类C中的成员函数能否引用间接基类A和直接基类B中的数据成员i,k,m? (5)能否在main函数中用d1.f1(), d1.f2(), d1.f3(), d1.f4(), d1.f5()调用f1,f2,f3,f4, f5成员函数? (6)派生类d的成员函数f5能否调用成员函数f1,f2,f3,f4?
(1) 不可以,b1.i和b1.m都是派生类B中的私有成员,不能在类外访问;b1.k是派生类B中的公共成员,可以在类外访问。
(2) 不可以,d1.i、d1.k、d1.m、d1.n、d1.p、d1.q和d1.r都不能在类外访问。因为派生类D继承了类C的保护成员和私有成员,类C又继承了类B的公共成员、保护成员和私有成员,所以在类外都不能访问。
(3) 可以,派生类B中的成员函数可以调用基类A中的所有成员函数,包括公共成员函数、保护成员函数和私有成员函数。
(4) 不可以,派生类C只能访问直接基类B中的公共成员和保护成员,不能访问间接基类A中的成员。
(5) 只能用d1.f5()调用成员函数f5,其他函数都不能在类外访问。因为派生类D继承了类C的保护成员和私有成员,类C又继承了类B的公共成员、保护成员和私有成员,所以在类外都不能访问。
(6) 不可以,派生类D无法访问类C和类B中的成员函数和数据成员,更无法访问类A中的成员函数和数据成员。
阅读全文