多重继承

多重继承

C++中所有的继承都是实现继承。because everything in a base class, 

interface and implementation, becomes part of a derived class.

接口继承仅仅是在一个派生类接口中加入了成员函数的声明。在C++中不支持这种用法。C++中模拟接口继承的技术是从一个接口类(只有声明,没有数据成员和函数体)派生一个类。除了析构函数以外,这些声明都是纯虚函数。

1、强类型与弱类型

对于动态语言与静态语言的区分,套用一句流行的话就是:Static typing when possible, dynamic typing when needed。

“动”或“静”,强调的是实施类型的时间,编译里就要确定类型的是静态类型,比如C/C++/JAVA/C#,运行时才实施类型的则是动态类型,比如VB/Python。   

而“强”或“弱”则强调实施类型的强度,强类型的语言,如C++等,变量的类型不可随意转换;而弱类型的语言,变量的类型可以随需要任意转换,而且通常都是隐式的。

静态类型语言是指在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型,某些具有类型推导能力的现代语言可能能够部分减轻这个要求.

动态类型语言是在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。

强类型语言是一旦变量的类型被确定,就不能转化的语言。实际上所谓的貌似转化,都是通过中间变量来达到,原本的变量的类型肯定是没有变化的。

弱类型语言则反之,一个变量的类型是由其应用上下文确定的。比如语言直接支持字符串和整数可以直接用 + 号搞定。当然,在支持运算符重载的强类型语言中也能通过外部实现的方式在形式上做到这一点,不过这个是完全不一样的内涵 

2、多重继承的一个使用

一个引用计数的数据库连接。

3、多重继承的问题

会有向上类型转换的二义性。我们可以使用虚继承来解决。

继承和派生(二)

http://blog.163.com/zhoumhan_0351/blog/static/39954227201002854625174

如下一个例子说明初始化问题:

//: C08:IntermediateCast.cpp

#include <iostream>

using namespace std;

class Top {

protected:

  int x;

public:

  Top(int n) { x = n; }

  virtual ~Top() {}

  friend ostream&

  operator<<(ostream& os, const Top& t) {

    return os << t.x;

  }

};

class Left : virtual public Top {

protected:

  int y;

public:

  Left(int m, int n) : Top(m) { y = n; }

};

class Right : virtual public Top {

protected:

  int z;

public:

  Right(int m, int n) : Top(m) { z = n; }

};

class Bottom : public Left, public Right {

  int w;

public:

  Bottom(int i, int j, int k, int m)

  : Top(i), Left(0, j), Right(0, k) { w = m; }

  friend ostream&

  operator<<(ostream& os, const Bottom& b) {

    return os << b.x << ',' << b.y << ',' << b.z

      << ',' << b.w;

  }

};

int main() {

  Bottom b(1, 2, 3, 4);

  cout << sizeof b << endl;

  cout << b << endl;

  cout << static_cast<void*>(&b) << endl;

  Top* p = static_cast<Top*>(&b);

  cout << *p << endl;

  cout << static_cast<void*>(p) << endl;

  cout << dynamic_cast<void*>(p) << endl;

} ///:~

4、多重继承的初始化

继承和派生(一)

http://blog.163.com/zhoumhan_0351/blog/static/3995422720100284731826

1.All virtual base class subobjects are initialized, in top-down, left-to-right 

order according to where they appear in class definitions.

2.Non-virtual base classes are then initialized in the usual order.

3.All member objects are initialized in declaration order.

4.The complete object’s constructor executes.

#include <iostream>

#include <string>

using namespace std;

class M {

public:

  M(const string& s) { cout << "M " << s << endl; }

};

class A {

  M m;

public:

  A(const string& s) : m("in A") {

    cout << "A " << s << endl;

  }

  virtual ~A() {}

};

class B {

  M m;

public:

  B(const string& s) : m("in B")  {

    cout << "B " << s << endl;

  }

  virtual ~B() {}

};

class C {

  M m;

public:

  C(const string& s) : m("in C")  {

    cout << "C " << s << endl;

  }

  virtual ~C() {}

};

class D {

  M m;

public:

  D(const string& s) : m("in D") {

    cout << "D " << s << endl;

  }

  virtual ~D() {}

};

class E : public A, virtual public B, virtual public C {

  M m;

public:

  E(const string& s) : A("from E"), B("from E"),

  C("from E"), m("in E") {

    cout << "E " << s << endl;

  }

};

class F : virtual public B, virtual public C, public D {

  M m;

public:

  F(const string& s) : B("from F"), C("from F"),

  D("from F"), m("in F") {

    cout << "F " << s << endl;

  }

};

 

class G : public E, public F {

  M m;

public:

  G(const string& s) : B("from G"), C("from G"),

  E("from G"),  F("from G"), m("in G") {

    cout << "G " << s << endl;

  }

};

int main() {

  G g("from main");

} ///:~

   虚基类初始化不重复进行。

5、名字查找问题

以基类名作为限定符以消除二义性。

此外,In general, a name A::f dominates the name B::f if A derives 

from B, directly or indirectly, or in other words, if A is “more derived” 

in the hierarchy than B。Therefore, in choosing between two functions 

with the same name, the compiler chooses the one that dominates. If there 

is no dominant name, there is an ambiguity.

// Illustrates initialization order with virtual bases.

#include <iostream>

using namespace std;

class A {

public:

  virtual ~A() {}

  virtual void f() { cout << "A::f\n"; }

};

class B : virtual public A {

public:

  void f() { cout << "B::f\n"; }

};

class C : public B {};

class D : public C, virtual public A {};

int main() {

  B* p = new D;

  p->f(); // Calls B::f()

  delete p;

} ///:~

6、避免使用多重继承

如果以下两个问题中一个不满足,则不应当使用多重继承。

1.Do you need to show the public interfaces of both these 

classes through your new type? (See instead if one class can be 

contained within the other, with only some of its interface exposed 

in the new class.)

2.Do you need to upcast to both of the base classes? (This also 

applies when you have more than two base classes.)

    多重继承被称作百分之90的GOTO语句。

参考:

1、Thinkin in C++

2、http://hi.baidu.com/soulmachine/blog/item/1de1bbc3414ec754b219a83 d.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值