标签:
下面用代码来说明下:
#include <iostream> using namespace std; class Bed {//床 public: Bed(int weight) : weight_(weight) { } void sleep() { cout<<"sleep ..."<<endl; } int weight_; }; class Sofa {//沙发 public: Sofa(int weight) : weight_(weight) { } void watchTV() { cout<<"watch TV ..."<<endl; } int weight_; }; class SofaBed : public Bed, public Sofa {//沙发床,公有继承自床类与沙发类 public: void foldOut() {//可以折叠出来 cout<<"foldOut ..."<<endl; } void foldIn() {//可以收缩起来 cout<<"foldIn ..."<<endl; } int weight_; }; int main(void) { SofaBed sofaBed; return 0; }
编译:
因为需要初始化父类,所以需要在SofaBed中默认构造中去处理:
下面对其沙发床的weight_属性赋值,由于简单起见,它是public的,所以可以直接在类的外部去赋值:
可以用域运算符去访问:
但是,上面代码中有点不妥:
所以更改代码如下:
#include <iostream> using namespace std; class Furniture {//家具 public: Furniture(int weight) : weight_(weight) { } int weight_; }; class Bed : public Furniture{//床 public: Bed(int weight) : Furniture(weight) { } void sleep() { cout<<"sleep ..."<<endl; } }; class Sofa : public Furniture{//沙发 public: Sofa(int weight) : Furniture(weight) { } void watchTV() { cout<<"watch TV ..."<<endl; } }; class SofaBed : public Bed, public Sofa {//沙发床,公有继承自床类与沙发类 public: SofaBed(int weight) : Bed(weight), Sofa(weight) { } void foldOut() {//可以折叠出来 cout<<"foldOut ..."<<endl; } void foldIn() {//可以收缩起来 cout<<"foldIn ..."<<endl; } int weight_; }; int main(void) { SofaBed sofaBed(10); /*sofaBed.weight_ = 10; sofaBed.weight_ = 20;*///ERROR,访问不明确 //sofaBed.Sofa::weight_ = 10; //sofaBed.Bed::weight_ = 20; sofaBed.watchTV(); sofaBed.foldOut(); sofaBed.sleep(); return 0; }
编译运行正常,但是此时如果更改weight_属性呢?
仍然提示访问不明确,为什么呢?
所以解决方法还是用域访问去解决:
所以说多继承就会有二义性产生,那上面这个沙发类还是有问题呀,居然有两个weight_,那就没有办法解决了么?答案是否定的,解决办法请看下面
具体代码如下:
#include <iostream> using namespace std; class Furniture {//家具 public: Furniture(int weight) : weight_(weight) { } int weight_; }; class Bed : virtual public Furniture{//床 public: Bed(int weight) : Furniture(weight) { } void sleep() { cout<<"sleep ..."<<endl; } }; class Sofa : virtual public Furniture{//沙发 public: Sofa(int weight) : Furniture(weight) { } void watchTV() { cout<<"watch TV ..."<<endl; } }; class SofaBed : public Bed, public Sofa {//沙发床,公有继承自床类与沙发类 public: SofaBed(int weight) : Bed(weight), Sofa(weight) { } void foldOut() {//可以折叠出来 cout<<"foldOut ..."<<endl; } void foldIn() {//可以收缩起来 cout<<"foldIn ..."<<endl; } int weight_; }; int main(void) { SofaBed sofaBed(10); sofaBed.weight_ = 20; sofaBed.watchTV(); sofaBed.foldOut(); sofaBed.sleep(); return 0; }
编译:
报错了,因为虚基类的构造函数会涉及到一些问题,这个在下面会学习到,这里为了说明用虚基类能解决二义性,先暂且去掉带参数的构造函数,让其代码编译通过:
#include <iostream> using namespace std; class Furniture {//家具 public: //Furniture(int weight) : weight_(weight) { //} int weight_; }; class Bed : virtual public Furniture{//床 public: //Bed(int weight) : Furniture(weight) { //} void sleep() { cout<<"sleep ..."<<endl; } }; class Sofa : virtual public Furniture{//沙发 public: //Sofa(int weight) : Furniture(weight) { // //} void watchTV() { cout<<"watch TV ..."<<endl; } }; class SofaBed : public Bed, public Sofa {//沙发床,公有继承自床类与沙发类 public: //SofaBed(int weight) : Bed(weight), Sofa(weight) { //} void foldOut() {//可以折叠出来 cout<<"foldOut ..."<<endl; } void foldIn() {//可以收缩起来 cout<<"foldIn ..."<<endl; } int weight_; }; int main(void) { //SofaBed sofaBed(10); SofaBed sofaBed; sofaBed.weight_ = 20; sofaBed.watchTV(); sofaBed.foldOut(); sofaBed.sleep(); return 0; }
编译运行这时就正常了,也不存在二义性了,而此时的类结构就变为了:
说明这个问题之后,再来解释刚才有带参数的构造的问题,如下:
#include <iostream> using namespace std; class Furniture {//家具 public: Furniture(int weight) : weight_(weight) { } int weight_; }; class Bed : virtual public Furniture{//床 public: Bed(int weight) : Furniture(weight) { } void sleep() { cout<<"sleep ..."<<endl; } }; class Sofa : virtual public Furniture{//沙发 public: Sofa(int weight) : Furniture(weight) { } void watchTV() { cout<<"watch TV ..."<<endl; } }; class SofaBed : public Bed, public Sofa {//沙发床,公有继承自床类与沙发类 public: SofaBed(int weight) : Bed(weight), Sofa(weight), Furniture(weight) { } void foldOut() {//可以折叠出来 cout<<"foldOut ..."<<endl; } void foldIn() {//可以收缩起来 cout<<"foldIn ..."<<endl; } int weight_; }; int main(void) { SofaBed sofaBed(10); sofaBed.weight_ = 20; sofaBed.watchTV(); sofaBed.foldOut(); sofaBed.sleep(); return 0; }
这时就可正常编译了,由于基类Furniture没有提供默认构造函数,所以在它的所有派生类中,不管是直接或间接的都需要去显示的构造Furniture才行,这也就是问题之所在。
#include <iostream> using namespace std; class Furniture {//家具 public: Furniture(int weight) : weight_(weight) { cout<<"Furniture ..."<<endl; } ~Furniture() { cout<<"~Furniture ..."<<endl; } int weight_; }; class Bed : virtual public Furniture{//床 public: Bed(int weight) : Furniture(weight) { cout<<"Bed ..."<<endl; } ~Bed() { cout<<"~Bed ..."<<endl; } void sleep() { cout<<"sleep ..."<<endl; } }; class Sofa : virtual public Furniture{//沙发 public: Sofa(int weight) : Furniture(weight) { cout<<"Sofa ..."<<endl; } ~Sofa() { cout<<"~Sofa ..."<<endl; } void watchTV() { cout<<"watch TV ..."<<endl; } }; class SofaBed : public Bed, public Sofa {//沙发床,公有继承自床类与沙发类 public: SofaBed(int weight) : Bed(weight), Sofa(weight), Furniture(weight) { cout<<"SofaBed ..."<<endl; } ~SofaBed() { cout<<"~SofaBed ..."<<endl; } void foldOut() {//可以折叠出来 cout<<"foldOut ..."<<endl; } void foldIn() {//可以收缩起来 cout<<"foldIn ..."<<endl; } int weight_; }; int main(void) { SofaBed sofaBed(10); sofaBed.weight_ = 20; sofaBed.watchTV(); sofaBed.foldOut(); sofaBed.sleep(); return 0; }
编译运行:
也就说明了其它派生类调用基类的构造函数就被忽略了,也就是这个意思~
标签:
原文地址:http://www.cnblogs.com/webor2006/p/5621606.html