如何备考等考C++与面向对象:多重继承2016/5/14 12:22:13 | 来源:中国教育在线 | 发布者: | 查看:1242次

先看这个:

class base

{

public:

int b;

void print() {cout 《 "base" 《 endl;}

};

class derived1 : public base

{

public:

int d1;

};

class derived2 : public base

{

public:

int d2;

};

class grandson : public derived1,public derived2

{

public:

int g;

};

这里,我们让derived1和derived2继承base,再让grandson继承derived1和derived2,我们是想实现一个菱形结构:

我们可以写出主程序:

void main()

{

grandson gs;

// gs.b = 1;

// gs.base::b = 1;

// gs.print();

}

看见我加注释的那三句话了吗?每句都会报错的!为什么那?

因为,想实现棱形结构只是我们的一厢情愿!我们又没告诉编译器,编译器哪有那么聪明!

实际结构是这样的:

所以我们应该这样写main函数:

void main()

{

grandson gs;

gs.derived1::b = 1;

gs.derived2::b = 1;

gs.derived1::print();

gs.derived2::print();

}

可以看到,从基类base继承来的成员b和print()函数在grandson中都有两份,这可不是我们想要的!因为这两个b是一样的,都是从base来的;print()也是!

其实,这个问题很好解决,科学家发明了关键字virtual来解决这个问题:

class base

{

public:

int b;

void print(){cout 《 "base" 《 endl;}

};

class derived1 : virtual public base

{

public:

int d1;

};

class derived2 : virtual public base

{

public:

int d2;

};

class grandson : public derived1,public derived2

{

public:

int g;

};

现在我们可以这样写主函数了:

void main()

{

grandson gs;

gs.b = 1;

gs.base::b = 1;

// gs.derived1::b = 1;

// gs.derived2::b = 1;

gs.print();

// gs.derived1::print();

// gs.derived2::print();

}

现在,grandson的b和print都只有一份了,所以编译器不会再告诉我们“ambiguous”了!

当然,按我加注释那几句那么写也没问题,反正现在b和print()都是各占一份内存空间,不再分derived1和derived2继承过来的,是从他们两个共同从base继承过来的。

请注意,对于base,我们什么也没做,他现在就叫做虚基类,因为derived1和derived2在继承时加了关键字virtual!

在现实世界中这种情况是很多见的,比如公司的临时销售人员,又有销售人员的属性,也有临时人员的属性;还有中国老师上课常用的老师和研究生派生的助教的例子,等等。

总之,你只要记住:当你想实现棱形结构时,请使用virtual!

凡本站注明“稿件来源:新科教育”的所有图文音视频,版权均属新科所有,任何媒体、网站或个人未经本网协议授权不得转或以其他方式复制发表。已获得本站协议 授权的媒体、网站,在下载使用时必须注明“稿件来源:新科教育”,违者本站将依法追究责任。
热门课程
  • 您的电话:

您好,新科教育精品课程
找到了感兴趣的课程!