关于c++中的类继承以及类初始化顺序

来源:互联网 发布:java面试框架问题 编辑:程序博客网 时间:2024/06/05 07:14
  

对于类以及类继承, 几个主要的问题:

1) 继承方式: public/protected/private继承. 这是c++搞的,实际上继承方式是一种允许子类控制的思想. 子类通过public继承, 可以把基类真实还原, 而private继承则完全把基类屏蔽掉.这种屏蔽是相对于对象层而言的, 就是说子类的对象完全看不到基类的方法, 如果继承方式是private的话,即使方法在基类中为public的方法. 但继承方式并不影响垂直方向的访问特性, 那就是子类的函数对基类的成员访问是不受继承方式的影响的.

比较(java): java是简化的, 其实可认为是c++中的public继承.实在没必要搞private/protected继承, 因为如果想控制,就直接在基类控制就好了.

2)  对象初始化顺序: c++搞了个成员初始化列表,并确明确区分初时化跟赋值的区别. c++对象的初始化顺序是:

    (a)基类初始化

    (b)对象成员初时化

    (c)构造函数的赋值语句

假设 class C :  public A, public B {

       D d;//

    }

则初始化的顺序是A, B, D, C的构造函数. 这里基类的初始化顺序是按照声明的顺序, 成员对象也是按照声明的顺序. 因此c(int i, int j) : B(i), A(j) {} //这里成员初始化列表的顺序是不起作用的

析构函数的顺序则刚好是调过来, 构造/析构顺序可看作是一种栈的顺序

比较(java): java中初始化赋值是一回事. 而且对基类的构造函数调用必须显示声明, 按照你自己写的顺序. 对成员对象,也叫由你初始化. 没有什么系统安排的顺序问题, 让你感觉很舒服

3) 多继承问题: c++支持多继承, 会导致"根"不唯一. 而java则没有该问题;此外c++没有统一的root object, java所有对象都存在Object类使得很多东西很方便. 比如公共的seriall,persistent等等.

4) 继承中的重载 c++中,派生类会继承所有基类的成员函数, 但构造函数, 析构函数除外. 这意味着如果B 继承A, A(int i)是基类构造函数, 则无法Bb(i)定义对象. 除非B也定义同样的构造函数. c++的理由是, 假如派生类定义了新成员,则基类初始化函数无法初始化派生类的所有新增成员.

比较(java): java中则不管, 就算有新增对象基类函数没有考虑到, 大不了就是null, 或者你自己有缺省值.也是合理的.

5) 继承中的同名覆盖和二义性: 同名覆盖的意思是说,当派生类跟基类有完全一样的成员变量或者函数的时候, 派生类的会覆盖基类的. 类似于同名的局部变量覆盖全局变量一样.但被覆盖的基类成员还是可以访问的.

如B继承A, A, B都有成员变量a,则B b, b.a为访问B的a, b.A::a则为访问基类中的a. 这对于成员函数也成立.但需要注意的是, 同名函数必须要完全一样才能覆盖. int func(int j)跟int func(long j)其实是不一样的.如果基类,派生类有这两个函数, 则不会同名覆盖. 最重要的是, 两者也不构成重载函数. 因此加入A有函数int func(intj), B有函数int func(long j). 则B的对象b.func(int)调用为错误的.因为B中的func跟它根本就不构成重载.

   同名覆盖导致的问题是二义性.加入C->B=>A, 这里c继承B, B继承A. 假如A,B都有同样的成员fun, 则C的对象c.fun存在二义性. 它到底是指A的还是B的fun呢?解决办法是用域限定符号c.A::fun来引用A的fun.

另外一个导致二义性的是多重继承. 假设B1, B2都继承自B, D则继承B1, B2. 那么D有两个B而产生二义性.

这种情况的解决办法是用虚基类. class B1 : virtual public B,class B2:virtual public B, 

D则为class D : public B1, public B2.这样D中的成员只包含一份B的成员使得不会产生二义性.

比较(java). java中是直接覆盖. 不给机会这么复杂, 还要保存基类同名的东西. 同名的就直接覆盖,没有同名的就直接继承.

  虚基类的加入, 也影响到类的初始化顺序.原则是每个派生类的成员化初始化列表都必须包含对虚基类的初始化. 最终初始化的时候, 只有真正实例化对象的类的调用会起作用.其它类的对虚基类的调用都是被忽略的. 这可以保证虚基类只会被初始化一次.

 


0 0
原创粉丝点击