网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
3. 多继承中从每个基类中继承的状态
在多继承中,子类的对象包含每个基类的子对象,比如Sub继承Base1,Base2,Base1又继承自Base,那么Sub对象的结构如下图:
构造一个派生类的对象将同时构造并初始化它的所有基类子对象,并且多重继承的派生类的构造函数值也只能初始化它的直接子类。
子类的构造方法初始值列表将实参分别传递给每个直接父类。父类的构造顺序与派生列表中基类的出现顺序保持一致,而与派生类构造函数初始值列表中基类的顺序无关。怎么理解这句话呢?就是构造顺序与class Sub : public Base1, public Base2
这个顺序有关,而与Sub::Sub(std::string name):Base1(name),Base2(){}
没有关系。
在C++11新标准中,允许派生类从它的一个或几个基类中继承构造函数,但是如果从多个基类中集成了相同的构造函数,程序就会出错。
比如Base1,Base2 都有以const st::string&
参数的构造函数,那么Sub同时继承Base1,Base2就会出错,这个时候我们必须专门为Sub定义自己的构造函数Sub:Sub(const std::string &s):Base1(s),Base2(s)
。
4. 多重继承中的类型转换
子类继承多个父类的情况下,我们可以令某个可访问基类的指针或引用直接指向一个子类对象。比如:
Base1 *base1 = new Sub();
Base2 *base2 = new Sub();
Base base = new Sub();
编译器不会在子类像基类的几种转换中进行比较和选择,因为它认为转换成哪个父类都行。但是这样会带来二义性,比如重载方法时:
void action(const Base1&);
void action(const Base2&);
当我们给action传Sub对象时就会出问题,因为编译器不知道怎么转换了。
所以我们在重载方法时要注意这种类型转换可能引起的问题。
5. 多重继承中的资源查找
在Java中我们查找属性时先从子类找,找不到再找父类,C++也是类似,但是在多重继承的结构中可能会有些复杂。
因为在查找过程中,会在所有直接基类中同时进行,如果名字在多个基类中都被找到,则这个属性的名字就产生了二义性。
我们思考一个问题,在Java中,如果我们定义了两个接口A,B,它们都有void test()
这么一个方法,那么我们的Test类如果同时实现了A,B接口,具体的类该怎么实现呢?
在Java中确实比较简单,只需要实现一个test()方法就可以,但是在C++的多重继承中,父类不仅有方法还有属性,这种二义性该怎么解决呢?在C++中,对于一个派生类来说,从它的几个基类中分别继承名字相同的成员是完全合法的,只是需要在我们使用这些名字是加上前缀限定符明确指定它属于哪个基类(不调用不会出错,如果调用了还没有加前缀就会出错)。
比如上面说的test方法,我们的子类可以使用sub->Base1::text()
方法来调用。
还有一种更复杂的情况,就是派生类继承的两个基类有函数名相同,但是参数列表不同的方法,这样查找是更容易出错。
**最佳实践:**为了避免二义性,除了我们在调用时加前缀,最好的办法是在派生类中为这个函数定义一个自己的版本,在函数内部来屏蔽这些二义性。比如:
int Sub::getMax() const
{
return std::max(Base1::getMax(), Base2::getMax());
}
6. 虚继承
我们在派生类列表中见过这么一种形式:
class Base1:public virtual Base{
...
}
virtual代表虚继承,那么虚继承是做什么,要解决什么问题呢?
比如这样的一种结构:
class Base{
protected:
int num;
}
class Base1:public Base{
}
class Base2:public Base{
}
class Sub:public Base1, Base2{
}
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
s://bbs.csdn.net/topics/618668825)**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!