您的位置:首页 > 编程语言 > C语言/C++

c++多重继承 和 初始化列表

2014-10-27 11:51 176 查看
#include<iostream>

using namespace std;

class human

{

public:
human(int);
virtual ~human(){cout<<"析构人类"<<endl;}
virtual int walk(){return itwalk;}
virtual void setwalk(int w){itwalk=w;}

private:
int itwalk;

};

human::human(int a):itwalk(a)

{

     cout<<"人类的构造函数"<<endl;

}

class father:public human

{

public:
father(int walk,int swit);
virtual ~father(){cout<<"析构父亲"<<endl;}
virtual int getwit(){return itswit;}

     virtual int walk(){return itwalk;}
virtual void setwalk(int w){itwalk=w;}

private:
int itwalk;
int itswit;

};

father::father(int walk,int swit):human(walk),itwalk(walk),itswit(swit)

{

cout<<"创建父亲"<<endl;

}

class mother:public human

{

public:
mother(bool sex,int walk);
virtual ~mother(){cout<<"析构母亲"<<endl;}
virtual bool sex()const{return itsex;}
virtual void setsex(bool sex){itsex=sex;}

protected:
bool itsex;

};

mother::mother(bool sex,int walk):human(walk),itsex(sex)
{

           cout<<"构造母亲"<<endl;
}

class son:public father,public mother

{

public:
void beautiful()const{cout<<"儿子也很帅\n"<<endl;}
son(bool sex,int walk,int swit);
~son(){cout<<"析构儿子"<<endl;}

        virtual int getwit(){return itswit;}

        virtual bool sex()const{return itsex;}

        virtual int walk(){return itwalk;}

        virtual void setsex(bool sex){itsex=sex;}

private:
int itswit;

    int itwalk;
bool itsex;

};

son::son(bool sex,int walk,int swit):father(walk,swit),mother(sex,walk)//,itsex(sex),itswit(swit),itwalk(walk)

{

     cout<<"构造儿子\n"<<endl;
 itswit=sex;
itwalk=walk;
itsex=swit;

}

int main()

{
son *ps=new son(true,50,80);

  cout<<ps->walk()<<endl;

  ps->father::setwalk(80);

  cout<<ps->father::walk()<<endl;

  cout<<ps->walk()<<endl;
delete ps;
return 0;

}

1.子类继承父类后  子类的数据成员分析:

假定A类 有成员   a,b,c

B类有成员 a,b,c 

class C:public A,public B 

{

C(int x,int y,int z);

   int a,b,c;

};

那么  C类里面有成员 A::a,b,c   B::a,b,c  C::a,b,c

}

于是 初始化列表为  C(int x,int y,int z):A(x,y,z),B(x,y,z),a(x),b(y),c(z){}

也可以写成C(int x,int y,int z):A(x,y,z),B(x,y,z)

{

 
4000
   a=x;b=y;c=z;

}

下面就是这回事

son::son(bool sex,int walk,int swit):father(walk,swit),mother(sex,walk)//,itsex(sex),itswit(swit),itwalk(walk)
{
     cout<<"构造儿子\n"<<endl;
  itswit=sex;
 itwalk=walk;
 itsex=swit;
}

C++初始化成员列表:

1. 简述

    主要的场合有四类:初始化对象成员,初始化基类的成员,初始化const成员,初始化引用成员。对于const成员和引用成员,比较简单,这两种变量都要求初始化后不能赋值,因此,只能在成员初始化列表中进行初始化,其他地方不行。本文主要介绍初始化对象成员和初始化基类成员这两种情况。  

2. 初始化对象成员

    具体分为两种情况:第一,该对象具有“无参数的构造函数”,使用初始化成员列表,有可能提升性能;第二,该对象只有“有参数的构造函数”,这种情况,必须使用初始化成员列表。   

#include <iostream>
using namespace std;

class AK_Zero_Parameter { // 只有默认的无参数构造函数 
}; 
class AK_One_Parameter {

  int m_value;
public:

  AK_One_Parameter(int value) { // 只有一个有参数构造函数 
    m_value = value;

  } 

};
class Guns {

  AK_Zero_Parameter ak_1;

  AK_One_Parameter ak_2;
public:

  // ak_1的构造函数,ak_2的构造函数
  Guns(int value):ak_2(value){}  

  // ak_1的构造函数,ak_2的拷贝构造函数 
  Guns(AK_One_Parameter ak_one):ak_2(ak_one) {}

  // ak_1的构造函数,ak_2的构造函数,ak_2的赋值函数 
//Guns(AK_One_Parameter ak_one):ak_2(0) {  ak_2 = ak_one; }
};
int main() { 

   system("PAUSE"); 

   return 0;

}

    其实,Guns的构造过程,首先是构造函数内部调用之前,参考初始化列表,对成员进行初始化工作。顺序根据成员声明的顺序。

    首先,初始化ak_1,ak_1没有在列表中被指定,所以调用了ak_1的“无参数的构造函数”。

    然后,初始化ak_2,ak_2在列表中指定,调用对应的“有参数的构造函数”,如果ak_2也在列表中不指定的话,就必须调用ak_2的“无参数的构造函数”,编译器会在AK_One_Parameter这个类中去寻找,然后会发现找不到“无参数构造函数”,因此会编译失败。

    这里对于ak_1只调用了一次构造函数,并不存在效率提升。效率的提升体现在第二个构造函数与第三个构造函数。

    第二个构造函数,对于ak_2调用了一次拷贝构造函数。

    第三个构造函数,对于ak_2首先调用一次构造函数,然后在构造函数内部,调用了一次赋值函数。

3. 初始化基类的成员

class Gold_AK: AK_Zero_Parameter,AK_One_Parameter {
public:
  // 初始化基类AK_Zero_Parameter,初始化基类AK_One_Parameter   

  Gold_AK(int value):AK_One_Parameter(value) {};

}; 

    在上面的代码中,加入上面的代码。对于子类Gold_AK,其构造过程如下:

    首先,初始化基类AK_Zero_Parameter,由于在初始化列表中,没有任何指示,所以调用其“无参数的构造函数”。

    然后,初始化基类AK_One_Parameter,由于在初始化列表中,给出了明确指示,所以调用其“有参数的构造函数”。如果不在列表中给出指示的话,就会试图调用其无参数的构造函数,而其没有这样的函数,编译失败。所以,当基类只有“有参数的构造函数时”子类的构造函数中,必须使用成员初始化列表对齐进行指定。

4. 总结

    初始化对象成员和初始化基类成员,当只有“有参数的构造函数时”,必须在初始化成员列表中进行指示。其余情况,不是必须的,但是有时候,能够提升性能。

    此外,const成员和引用成员的初始化工作,必须在初始化成员列表中指示。

    初始化的顺序与列表无关,与变量声明的顺序有关,基类子类的顺序有关。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  继承 c++