Part7 继承与派生 7.4派生类的构造和析构

1派生类的构造函数

默认情况下:基类的构造函数不被继承,派生类需要定义自己的构造函数。
C++11 规定:可用using语句继承基类构造函数。但是只能初始化从基类继承的成员。这时派生类新增成员可以通过类内初始值进行初始化。

建议:如果派生类有自己新增的成员,且需要通过构造函数初始化,则派生类要自定义构造函数。
若不继承基类的构造函数:
  继承来的成员:自动调用基类构造函数进行初始化
  派生类的构造函数需要给基类的构造函数传递参数。

单继承(派生类只有一个直接基类的情况)时构造函数的定义语法:
  派生类名::派生类名(基类所需的形参,本类成员所需的形参):
  基类名(参数表), 本类成员初始化列表
  {
  //其他初始化;
  };

 

//单继承时的构造函数举例
#include<iostream>
using namespace std;
class B{
public:
    B();
    B(int i);
    ~B();
    void print() const;
private:
    int b;
};
B::B(){
    b = 0;
    cout << "B's default constructor called." << endl;
}
B::B(int i){
    b = i;
    cout << "B's constructor called." << endl;
}
B::~B(){
    cout << "B's destructor called." << endl;
}
void B::print() const{
    cout << b << endl;
}
class C: public B{
public:
    C();
    C(int i, int j);
    ~C();
    void print() const;
private:
    int c;
};
C::C(){
    c = 0;
    cout << "C's default contructor called." << endl;
}
C::C(int i, int j):B(i),c(j){
    cout << "C's constructor called." << endl;
}
C::~C(){
    cout << "C's destructor called." << endl;
}
void C::print() const{
    B::print();
    cout << c << endl;
}
int main(){
    C obj(5,6);
    obj.print();
    return 0;
}

 

构造函数的执行顺序:
  1 调用基类构造函数。
    顺序按照它们被继承时声明的顺序(从左向右)。
  2 对初始化列表中的成员进行初始化。
    顺序按照它们在类中定义的顺序。
    对象成员初始化时自动调用其所属类的构造函数。由初始化列表提供参数。
  3 执行派生类的构造函数体中的内容。

 

 


2派生类构造函数举例

//7-4派生类构造函数举例
#include<iostream>
using namespace std;
class Base1{//基类1,构造函数有参数
public:
    Base1(int i){
        cout << "Constructing Base1 " << i << endl;
    }
};
class Base2{//基类2,构造函数有参数
public:
    Base2(int j){
        cout << "Constructing Base2 " << j << endl;
    }
};
class Base3{//基类3,构造函数无参数
public:
    Base3(){
        cout << "Constructing Base3 *" << endl; 
    }
};
class Derived: public Base2, public Base1, public Base3{
public:
    Derived(int a, int b, int c, int d):Base1(a), member2(d), member1(c), Base2(b){}//此处的次序与构造函数的执行次序无关
private://派生类的私有对象成员
    Base1 member1;
    Base2 member2;
    Base3 member3;
};
int main(){
    Derived obj(1,2,3,4);
    return 0;
}

 

 

 


3派生类复制构造函数
派生类未定义复制构造函数的情况:
  编译器会在需要时生成一个隐含的复制构造函数;
  这个隐含复制构造函数,先调用基类的复制构造函数;
  再为派生类新增的成员执行复制。

派生类定义了复制构造函数的情况:
  一般都要为基类的复制构造函数传递参数。
  复制构造函数只能接受一个参数,既用来初始化派生类定义的成员,也将被传递给基类的复制构造函数。
  基类的复制构造函数形参类型是基类对象的引用,实参可以是派生类对象的引用
  如: C::C(const C &c1): B(c1) {…}

 

 


4派生类的析构函数
析构函数不被继承,派生类如果需要,要自行声明析构函数。
声明方法与无继承关系时类的析构函数相同。
不需要显式地调用基类的析构函数,系统会自动隐式调用。
先执行派生类析构函数的函数体,再调用基类的析构函数。

//7-5派生类对象析构举例
#include<iostream>
using namespace std;
class Base1{
public:
    Base1(int i){
        cout << "Constructing Base1 " << i << endl;
    }
    ~Base1(){
        cout << "Destructing Base1" << endl;
    }
};
class Base2{
public:
    Base2(int j){
        cout << "Constructing Base2 " << j << endl;
    }
    ~Base2(){
        cout << "Destructing Base2" << endl;
    }
};
class Base3{
public:
    Base3(){
        cout << "Constructing Base3 *" << endl;
    }
    ~Base3(){
        cout << "Destructing Base3" << endl;
    }
};
class Derived: public Base2, public Base1, public Base3{
public:
    Derived(int a, int b, int c, int d):Base1(a), member2(d), member1(c), Base2(b){}
private:
    Base1 member1;
    Base2 member2;
    Base3 member3;
};
int main(){
    Derived obj(1,2,3,4);
    return 0;
}

 

posted @ 2017-12-19 14:05  LeoSirius  阅读(313)  评论(0编辑  收藏  举报