曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 1949|回复: 0
打印 上一主题 下一主题

使用虚基类时的构造函数规则

[复制链接]

716

主题

734

帖子

2946

积分

超级版主

Rank: 9Rank: 9Rank: 9

积分
2946
跳转到指定楼层
楼主
发表于 2013-12-14 20:35:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
假设有下面的几个类定义:

[C++] 纯文本查看 复制代码
class A
{
int a;
public:
A(int n = 0) : a(n) {}
...
};
class B: public A
{
int b;
public:
B(int m = 0, int n = 0) : A(n), b(m)  {}
...
};
class C : public B
{
int c;
public:
C(int q = 0, int m = 0, int n = 0) : B(m, n), c(q) {}
...
};


上面代码中,几个类的声明与继承都是通常的情况。此时,C 类的构造函数只能调用 B 类的构造函数,而 B 类的构造函数只能调用 A 类的构造函数。这里,有一个信息向上传递的路径:C 类的构造函数将值 m 和 n 传递给 B 类的构造函数;而 B 类的构造函数又将值 n 传递给了 A 类的构造函数。

现在,假设 Worker 为一个虚基类,Singer 与 Waiter 都从其派生,而 SingingWaiter 则继承了 Singer 与 Waiter ,这是多重继承。如果给 Singingwaiter 添加如下一条构造函数:
  1. SingingWaiter(const Worker & wk, int p = 0, int v = other) : Waiter(wk, p), Singer(wk, v) {}
复制代码
在 Worker 为虚基类的这种情况下,上面第一个例子中所演示的信息自动传递将不起作用。假如可以传递,那么将有 Waiter 和 Singer 这两条不同的路径将 wk 传递给 Worker 对象,这样就会引起冲突。因此 C++ 规定,在基类为“虚”时,禁止信息通过中间类自动传递给基类。因此,参数 wk 中的信息不会传递给子对象 Waiter。但是,这么一来会跟一个规定相矛盾:编译器必须在构造对象之前构造基类对象组件。因此,在上述情况下,编译器会先直接跳去执行 Worker 的默认构造函数。

如果我们不希望默认构造函数来构造虚基类的对象,解决的办法是,显式地调用所需的基类构造函数。因此,改写上面的构造函数为:
SingingWaiter(const Worker & wk, int p = 0, int v = other) : Worker(wk), Waiter(wk, p), Singer(wk, v) {}

上述代码将显式地调用虚基类的构造函数 Work(const Work &) 。对于虚基类来说,这种用法是合法的,但对于非虚基类,则是非法的

总之,如果类有间接虚基类,那么除非只需使用该虚基类的默认构造函数,否则必须显式地调用该虚基类的某个构造函数。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-17 23:21 , Processed in 0.078430 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表