1. 异常处理
void test_exception(int x) {
if (x == 0)
throw runtime_error("x is 0.");
else if (x == 1)
throw logic_error("x is 1.");
else
throw exception("x is not 0 or 1.");
}
int main() {
try {
test_exception(0);
}
catch (exception e) {
cout << e.what() << endl;
}
}
第 13 行捕获 exception 类型的异常,这是所有异常的公共基类,所以它可以捕获任何类型的异常。如果换成异常派生类,则只能捕获对应类型的异常。
2. 虚继承
1. 虚继承的作用
虚继承用于解决重复继承问题。情况1:两个直接基类继承了同一个基类,当前类继承这两个直接基类会出问题。情况2:直接基类继承了一个基类,当前类同时继承直接基类和这个基类会出现问题。下面以情况1为例说明。
struct Example1 { void f1() { cout << "Example1" << endl; } };
struct Example2_1: virtual public Example1 { void f2_1() { cout << "Example2_1" << endl; } };
struct Example2_2: virtual public Example1 { void f2_2() { cout << "Example2_2" << endl; } };
struct Example3: public Example2_1, public Example2_2 { void f3() { cout << "Example3" << endl; } };
int main() {
Example3 ex3;
ex3.f1();
}
如果第2、3行不使用虚继承就会有二义性:第8行不明确调用从Example2_1继承来的f1函数还是从Example2_2继承来的f1函数。
2. 虚继承与构造、析构顺序
抽象基类:含有纯虚函数的类。虚基类:被以虚派生的方式继承的类。
在虚派生中,虚基类是由最低层的派生类初始化的。如Example1由Example3初始化。
struct Examplea {/**/};
struct Exampleb: public Examplea {/**/};
struct ExampleA {/**/};
struct Example: public Exampleb, public Example2_1, public virtual ExampleA {/**/};
构造顺序:按派生列表初始化直接或间接虚基类后,再按派生列表初始化普通基类。比如构造Example对象的顺序是:
- 直接基类Example2_1的虚基类Example1,直接虚基类ExampleA。
- 直接基类Exampleb(先Examplea再Exampleb),直接基类Example2_1。
- Example。
和普通继承一样,虚继承的析构顺序也是与构造顺序相反的。