精华内容
下载资源
问答
  • 多重继承的顺序理解

    分析代码示例:

    #include <iostream>
    
    using namespace std;
    
    class X
    {
    	public: X()
    	{
    		cout<<"X ";
    	}
    };
    class Y 
    {
    	public: Y()
    	{
    	cout<<"Y ";
    	}
    };
    class Z 
    {
    	public: Z()
    	{
    		cout<<"Z ";
    	}
    };
    class A 
    {
    	public: A()
    	{
    		cout<<"A ";
    	}	
    };
    class B 
    {
    	public: B()
    	{
    		cout<<"B ";
    	}
    };
    class C : public B, virtual public A  
    {
    	public: C()
    	{
    		cout<<"C ";
    	}
    };
    class D : public B, virtual public A  
    {
    	public: D()
    	{
    		cout<<"D ";
    	}
    };
    class E : public C, virtual public D, virtual public Z
    {     public:
        X objX;
        Y objY;
        E()
        {
        	cout<<"E ";
        }
    };
    int main() 
    {      
    	E obj; 
    }
    
    

    输出结果:

    A B D Z B C X Y E

    按步骤debug:

    在这里插入图片描述

    多重继承的顺序分析

    主要遵循以下几点:
    1.先执行各基类的构造函数,再执行对象成员构造函数,后执行派生类构造函数
    注:
    ①处于同一层次的各基类构造函数的执行顺序与声明派生类时所指定的各基类顺序一致,而与派生类的构造函数定义中初始化列表顺序无关。
    ②若父类构造函数带有参数,必须在最远继承子类初始化列表调用。

    2.析构函数的执行顺序与构造函数相反。

    3.若同一层次中同时包含虚基类和非虚基类,先调用虚基类的构造函数,再调用非虚基类的构造函数。

    4.同一层次中的非虚基类只调用一次。

    5.如果派生类的成员与基类的某个成员同名,则派生类将在其作用域隐藏掉该基类成员。(C++ Prime 5)

    依据如上分析,则示例代码中:
    由3,找到classD
    由3,找到classA并执行A()
    由1,找到classB并执行B()
    由1,执行classD的D()
    由3,找到classZ并执行Z()
    由3,找到classC
    由4,找到classB并执行B()
    由1,找到classX并执行X()
    由1,找到classY并执行Y()
    由1,执行E()
    得到结果A B D Z C B X Y E

    展开全文
  • 小编典典是的,可以保证,如介绍新算法以计算方法分辨率顺序(即C3线性化)...本地优先级排序意味着一类C(B1, ..., Bn)将在mro基类Bi中具有在继承列表中列出的顺序。一个例子也许可以更好地解释单调性:>>> c...

    小编典典

    是的,可以保证,如介绍新算法以计算方法分辨率顺序(即C3线性化)的文档中所述。

    不使用此算法的mro实现并不真正符合python语言(2.3版以上)。AFAIK当前所有实现 都 使用C3线性化。

    C3线性化满足局部优先级排序和单调性。本地优先级排序意味着一类C(B1, ..., Bn)将在mro基类Bi中具有在继承列表中列出的顺序。

    一个例子也许可以更好地解释单调性:

    >>> class A(object): pass

    >>> class B(object): pass

    >>> class C(object): pass

    >>> class D(object): pass

    >>> class E(object): pass

    >>> class K1(A,B,C): pass

    >>> class K2(D,B,E): pass

    >>> class K3(D,A): pass

    >>> class Z(K1,K2,K3): pass

    python2.2的旧mro( 不是 单调的),这些是上述类的线性化:

    L[A] = A O

    L[B] = B O

    L[C] = C O

    L[D] = D O

    L[E] = E O

    L[K1]= K1 A B C O

    L[K2]= K2 D B E O

    L[K3]= K3 D A O

    L[Z] = Z K1 K3 A K2 D B C E O

    # in current versions of python (2.3+):

    # L[Z] = Z K1 K2 K3 D A B C E O

    在这里,您可以看到,在的线性化中Z,类位于A之前D,而在其线性化中K3则位于 之后

    D。单调性是线性化的属性,因此在继承时不存在此类交换。如果某个类X在Y其父级的所有线性化中均在类之前,则Y在最终线性化中它也将在类之前。

    现在,如果我们考虑一堂课C(B1, ..., Bn)。按照局部优先顺序,这些类B1, ...,

    Bn将在的线性化中按该顺序找到C。通过单调性,我们无法Bi在Bi自身之前找到s的子类。由此可见,的线性化(C如果存在)必须以C和开头B1。

    请注意,在某些情况下,您 无法 计算线性化,而python会抱怨,例如:

    >>> class A(object):pass

    ...

    >>> class B(object, A): pass

    ...

    Traceback (most recent call last):

    File "", line 1, in

    TypeError: Cannot create a consistent method resolution

    order (MRO) for bases object, A

    但是,如果交换类,则可以线性化层次结构:

    >>> class B(A, object): pass

    ...

    >>> B.mro()

    [, , ]

    如果父类没有共同的基数(object显然不是其他基数),那么显然的线性化C(B1, ...,

    Bn)将以B1(除外object)的线性化开始,然后将遵循B2etc的线性化,并将以:的线性化结束Bn:

    >>> class A(object): pass

    ...

    >>> class B(object): pass

    ...

    >>> class A1(A): pass

    ...

    >>> class A2(A1): pass

    ...

    >>> class B1(B): pass

    ...

    >>> class C(object): pass

    ...

    >>> class C1(C): pass

    ...

    >>> class C2(C1):pass

    ...

    >>> class C3(C2): pass

    ...

    >>> class D(A2, B1, C3): pass

    ...

    >>> D.mro()

    [, , , , , , , , , , ]

    当Bis之间有一些通用子类时,事情开始变得怪异,在这种情况下python找到了您期望的不违反局部优先顺序和单调性的顺序,否则将引发错误。

    2021-01-20

    展开全文
  • 本文借鉴自 http://www.cnblogs.com/panyinghua/p/3283726.html当类有多个超类,而且超类中有相同方法时,继承顺序就很重要,如下:class A(def save(self):...) # A 中有self方法/ \/ \class B class C(def save...

    本文借鉴自 http://www.cnblogs.com/panyinghua/p/3283726.html

    当类有多个超类,而且超类中有相同的方法时,继承顺序就很重要,如下:

    class A

    (def save(self):...) # A 中有self方法

    / \

    / \

    class B class C

    (def save(self):...) # B 和 C 中都继承 A,只有C中重写save方法

    \ /

    \ /

    \ /

    class D # 继承 B 和 C

    旧式类

    在旧式类中,会根据深度优先(depth-first)的顺序来继承,由左至右依次查找save()方法,D -> B -> A ->C,当查到方法时,立刻放回,不在继续查找。

    # 例:

    class A:

    def __init__(self):

    print 'it is A'

    def save(self):

    print 'save method from A'

    class B(A):

    def __init__(self):

    print 'it is B'

    class C(A):

    def __init__(self):

    print 'it is C'

    def save(self):

    print 'save method from C'

    class D(B, C):

    def __init__(self):

    print 'it is D'

    d = D()

    d.save()

    # 结果 ==》

    it is D

    save method from A # 根据上边的顺序,查到A中的save方法,即返回。

    新式类

    新式类中会根据方法解析顺序(MRO)来进行搜索,广度优先,当查到对应方法属性时,立即返回,不再继续查找。

    __mro__属性,标记了python继承层次中父类的查找顺序,Python的多重继承机制就是按照__mro__的顺序进行查找,一旦找到对应属性,则查找马上返回。

    # 例 1

    class A(object):

    def __init__(self):

    print 'it is A'

    def save(self):

    print 'save method from A'

    class B(A):

    def __init__(self):

    print 'it is B'

    class C(A):

    def __init__(self):

    print 'it is C'

    def save(self):

    print 'save method from C'

    class D(B, C):

    def __init__(self):

    print 'it is D'

    print D.__mro__

    d = D()

    d.save()

    # 结果==》

    (, , , , )

    it is D

    save method from C

    # 例 2

    class A(object):

    def save(self):

    print ('save A')

    class B(object):

    def save(self):

    print ('save B')

    class C(object):

    def save(self):

    print ('save C')

    class D(B,C,A):

    pass

    print D.__mro__

    cla = D()

    cla.save()

    # 结果

    (, , , , )

    save B

    # 例 3

    class B(object):

    def foo(self):

    print ('foo B')

    def bar(self):

    print 'bar B'

    class A(object):

    def foo(self):

    print ('foo A')

    class C1(A, B):

    pass

    class C2(A, B):

    def bar(self):

    print 'bar C2'

    class D(C1, C2):

    pass

    print D.__mro__

    d = D()

    d.foo()

    d.bar()

    # 结果

    (, , , , , )

    foo A

    bar C2

    展开全文
  • 我知道对于经典类的多重继承,原则是“从左至右,深度优先”,那么我想问是,这里面是否还和在类定义时候先后顺序有关? 例如按如下顺序定义:Fu1(object)、Fu2(object)、Zi1(Fu1,Fu2)、Zi2(Fu1,Fu2)、GC(Zi1,...
  • C++多重继承的构造执行顺序: 1.首先执行虚基类的构造函数,多个虚基类的构造函数按照被继承的顺序构造; 2.执行基类的构造函数,多个基类的构造函数按照被继承的顺序构造; 3.执行成员对象的构造函数,多个成员对象...

    1.首先执行虚基类的构造函数,多个虚基类的构造函数按照被继承的顺序构造;
    2.执行基类的构造函数,多个基类的构造函数按照被继承的顺序构造;
    3.执行成员对象的构造函数,多个成员对象的构造函数按照声明的顺序构造;
    4.执行派生类自己的构造函数;
    5.析构以与构造相反的顺序执行

    展开全文
  • 多重继承的构造顺序

    2019-09-26 17:26:49
    class dyh:public a,virtual public b,public c,virtual public d { public: dyh() //:a(),b(),c(),d(),s(),ss() { cout类的继承顺序\n"; } protected: dd s; ff ss; }; int main() { dyh aa; cout; }
  • 主要介绍了Python多重继承的方法解析执行顺序,结合实例形式分析了Python多重继承时存在方法命名冲突情况的解析执行顺序与相关原理,需要的朋友可以参考下
  • scala的多重继承多重继承构造器执行顺序、基于traitAOP实现
  • python 多重继承的方法解析顺序 任何实现多重继承的语言都要处理潜在的命名冲突, 这种冲突由不相关的祖先类实现同名方法引起 &nbsp; class A: def say(self): print("A Hello:&...
  • 在Python的多重继承中,super()函数返回类指不是当前类父类,而是MRO列表中当前类下一个类。 什么是MRO列表? MRO即Method Resolution Order(方法解析顺序),调用方法时会对当前类及当前类所有父类...
  • python3 类的多重继承和 python2 的经典类相差比较远,需要使用到MRO...# 多重继承的写法: class 类名(父类名,子类名) # 规则:相同方法名的方法以及框架都继承父类,若不同名的方法则可以完全同时继承 # coding...
  • 今天看程序员面试宝典(第三版时)时,看到一个关于多重继承的问题。题目如下 #include using namespace std; class A { int a; }; class B  { int b; }; class C : public A, public B { int c; }...
  • C++入门经典-例8.6-多重继承的构造顺序 1:单一继承是先调用基类的构造函数,然后调用派生类的构造函数,但多重继承将如何调用构造函数呢?多重继承中的基类构造函数被调用的顺序以派生表中声明的顺序为准。派生表...
  • C++多重继承的构造与析构的次序 在C++的多重继承中含有虚基类,成员对象时很容易把构造与析构的顺序弄不清楚 下面看一段代码 #include <iostream> using namespace std; class OBJ1 { public: OBJ1() { ...
  • 多重继承关系初始化顺序

    千次阅读 2017-06-26 21:12:51
    多重继承关系初始化顺序 父类属性---》父类构造方法---》子类属性---》子类构造方法    说明:创建对象时,子类构造方法会自动调用父类构造方法,若子类有有参构造,则不会自动调用父类无参构造...
  • 1.继承只会继承父类方法,不能继承父类变量 2.要想继承父类变量,需要执行父类__init__(self)方法 3.下划线开头变量或方法,会被认为是受保护,不能直接点出来,但如果强制打出来话也一样能用,只是...
  • 1、多重继承的trait代码实战 2、多重继承构造器执行顺序 3、给予trait的AOP代码实现 该代码中PianoPlayer类继承了Human,在构造的时候按照从左到右的顺序进行构造,TTeacher和PianoPlayer是PianoTeacher的特性...
  • python 的类有经典类和新式类之分,在多重继承的时候,继承到的方法的搜索的顺序根据类的类型不同也是不同的。先来讲经典类:经典类的特点就是不继承自任何类: #coding:utf-8 classp_1: deffoo(self): print'...
  • 在查找使用了多重继承的属性时,会将所有基类按从“最特殊”的类型到“最不特殊”的类这种顺序进行排列。然后在搜索属性时,就会按这个顺序搜索,直至找到该属性的第一个定义。可通过类的__mro__属性查看其基类...
  • 因为 D 是直接继承 C 的,从逻辑上说,执行 C 中的 foo() 更加合理,因此新式类对多继承的处理更为合乎逻辑。 转载于:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 665
精华内容 266
关键字:

多重继承的顺序