练习18.29
已知如下所示的类继承关系:
class Class{...};
class Base : public Class{...};
class D1 : virtual public Base{...};
class D2 : virtual public Base {...};
class MI : public D1, public D2 {...};
class Final : public MI, public Class{...};
(a)当作用于一个Final对象时,构造函数和析构函数的执行次序分别是什么?
(b)在一个Final对象中有几个Base部分?几个Class部分?
(c)下面的哪些赋值运算将造成编译错误?
Base *pb; Class *pc; MI *pmi; D2 *pd2;
(a) pb = new Class;
(b) pc = new Final;
(c) pmi = pb;
(d) pd2 = pmi;
解答:
(a) Class -> Base -> D1 -> D2 -> MI -> Class -> Final
测试代码如下:
#include <iostream>
using namespace std;
struct Class{Class(){cout << "Class" << endl;}};
struct Base : public Class{Base(){cout << "Base" << endl;}};
struct D1 : virtual public Base{D1(){cout << "D1" << endl;}};
struct D2 : virtual public Base {D2(){cout << "D2" << endl;}};
struct MI : public D1, public D2 {MI(){cout << "MI" << endl;}};
struct Final : public MI, public Class{Final(){cout << "Final" << endl;}};
int main(){
Final fi;
}
(b)
这个从构造顺序中可以看出,有一个Base部分,有两个Class部分。
(c)
以下是clang3.4的错误输出,我认为比gcc的错误信息要好理解的多。
(a) error: assigning to 'Base *' from incompatible type 'Class *'
(b) error: ambiguous conversion from derived class 'Final' to base class 'Class':
struct Final -> struct MI -> struct D1 -> struct Base -> struct Class
struct Final -> struct Class
(c) error: assigning to 'Class *' from incompatible type 'Final *'
(d) error: assigning to 'MI *' from incompatible type 'Base *'
练习18.30
在Base中定义一个默认构造函数、一个拷贝构造函数和一个接受int形参的构造函数。在每个派生类中分别定义这三种构造函数,每个构造函数应该使用它的实参初始化其Base部分。
解答:
#include <iostream>
using namespace std;
class Class{
public:
Class() : num(0){}
Class(const Class& c) : num(c.num){}
Class(const int& i) : num(i){}
protected:
int num;
};
class Base : public Class{
public:
Base() : Class(), num(0){}
Base(const Base& b) : Class(b), num(b.num){}
Base(const int& i) : Class(i), num(i){}
protected:
int num;
};
class D1 : virtual public Base{
public:
D1() : Base(), num(0){}
D1(const D1& d) : Base(d), num(d.num){}
D1(const int& i) : Base(i), num(i){}
protected:
int num;
};
class D2 : virtual public Base {
public:
D2() : Base(), num(0){}
D2(const D2& d) : Base(d), num(d.num){}
D2(const int& i) : Base(i), num(i){}
protected:
int num;
};
class MI : public D1, public D2 {
public:
MI() : D1(), D2(), num(0){}
MI(const MI& mi) : D1(mi), D2(mi), num(mi.num){}
MI(const int& i) : D1(i), D2(i), num(i){}
protected:
int num;
};
class Final : public MI, public Class{
public:
Final() : MI(), num(0){}
Final(const Final& f) : MI(f), num(f.num){}
Final(const int& i) : MI(i), num(i){}
protected:
int num;
};
int main(){
Final fi;
}