曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 3157|回复: 0
打印 上一主题 下一主题

派生类中的构造与析构函数

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2011-12-2 12:46:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
派生类会继承基类的成员,在实例化派生类的对象时,必须调用基类的构造函数来初始化派生类对象中的基类成员。基类部分的初始化程序可以在派生类中显式调用基类的构造函数来实现,否则派生类的构造函数会调用基类的默认构造函数。

基类的构造函数和基类的赋值操作符不能被派生类继承,但派生类构造函数和赋值操作符可以调用基类的构造函数和复制操作符。

派生类的构造函数通常会调用基类的构造函数,用以初始化派生类的基类成员。如果派生类没有构造函数,那么忙派生类默认的构造函数会调用基类默认的构造函数。析构函数与构造函数的调用正好相反,因此派生类的析构函数的调用发生在调用基类的析构函数之前。
如果我们创建一个派生类对象,并且基类和派生类中都包含其它类的对象,那么在创建派生类对象时,首先执行的是基类成员对象的构造函数,其次是基类的构造函数,然后是派生类的成员对象,最后才是派生类的构造函数。析构函数的顺序刚好相反。

下面程序演示了基类和派生类的构造和析构调用顺序。在程序中,有一个 Point 类,一个构造函数,一个析构函数和 proteced 数据成员 (x 和 y) 。
[C++] 纯文本查看 复制代码

#include <iostream>
using namespace std;


class Point {
public:
        Point( int = 0, int = 0 );      //默认构造函数
        ~Point();                       //析构函数


protected:
        int x, y;                       //可以被派生类访问
};


Point::Point( int a, int b )
{
        x = a;
        y = b;


        cout << "Point constructor: "
             << '[' << x << ", " << y << ']' << endl;
}


Point::~Point()
{
        cout << "Point destructor: " 
             << '[' << x << "," << y << ']' << endl;
}


class Circle : public Point {
public:
        Circle( double r = 0.0, int x = 0, int y = 0 );


        ~Circle();
private:
        double radius;
};




Circle::Circle( double r, int a, int b ) : Point( a, b ) //调用基类构造函数
{
        radius = r;     //合法


        cout << "Circle constructor: radius is " << radius
             << '[' << x << "," << y << ']' << endl;
}


Circle::~Circle()
{
        cout << "Circle destructor: radius is " << radius
             << '[' << x << "," << y << ']' << endl;
}


int main()
{
        Point p(11, 32);


        cout << endl;


        Circle circle1( 4.5, 72, 29 );
        cout << endl;


        Circle circle2(10, 5, 5);
        cout << endl;


        return 0;
}

运行输出:
./derivedcon
Point constructor: [11, 32]

Point constructor: [72, 29]
Circle constructor: radius is 4.5[72,29]

Point constructor: [5, 5]
Circle constructor: radius is 10[5,5]

Circle destructor: radius is 10[5,5]
Point destructor: [5,5]
Circle destructor: radius is 4.5[72,29]
Point destructor: [72,29]
Point destructor: [11,32]
从上面的输出我们可以看到构造函数和析构函数的调用顺序:先是基类中的构造函数,然后再到派生类中的构造函数。先是派生类中的析构函数,然后再调用基类中的析构函数。

在创建 Circle 这个派生类的对象时,其构造函数 Circle() 被调用,该构造函数公有 3 个参数。 第一个参数 r 用来初始化 Circle 类的私有成员 radius ,而第 2 个和第 3 个参数则传递给基类 Point 中的构造函数用以初始化从基类继承过来的两个保护成员 x 和 y 。

假如派生类中的构造函数不需要初始化自己的成员,而只要初始化基类中的成员,那么只需要写成如下样式即可:
Circle(int a, int b) : Point(a, b) { };

下面是一个完整的例子:
[C++] 纯文本查看 复制代码

#include <iostream>
#include <typeinfo>
#include <cstdlib>
using namespace std;


class figure {
protected:
    double x, y;
public:
    figure(double i, double j)
    {
        x = i;
        y = j;
    }
    virtual double area() = 0;    //纯虚函数
};


class triangle : public figure {
public:
    triangle(double i, double j) : figure(i, j) { };
    double area()
    {
        return x * 0.5 * y;
    }
};


class rectangle : public figure {
public:
    rectangle(double i, double j) : figure(i, j) { }
    double area()
    {
        return x * y;
    }
};


class circle : public figure {
public:
    circle(double i, double j = 0) : figure(i, j) { }
    double area() 
    {
        return 3.14 * x * x;
    }
};


figure *factory ()
{
    switch(rand() % 3) {
    case 0:
        return new circle(10.0);
    case 1:
        return new triangle(10.1, 5.3);
    case 2:
        return new rectangle(4.3, 5.7);
    }
    return 0;
}


int main()
{
    figure *p;    //指向基类的指针
    int i;


    int t = 0, r = 0, c = 0;


    //生成并统计对象
    for (i = 0; i < 10; i++) {
        p = factory();    //生成一个对象


        cout << "Object is " << typeid(*p).name();
        cout << ". ";


        //统计对象
        if (typeid(*p) == typeid(triangle)) t++;
        if (typeid(*p) == typeid(rectangle)) r++;
        if (typeid(*p) == typeid(circle)) c++;


        //输出对象的面积
        cout << "Area is " << p->area() << endl;
    }


    cout << endl;
    cout << "Objects generated:\n";
    cout << "Triangles: " << t << endl;
    cout << "Rectangles: " << r << endl;
    cout << "Circles: " << c << endl;


    return 0;
}

运行输出:
Object is class rectangle. Area is 24.51
Object is class rectangle. Area is 24.51
Object is class triangle. Area is 26.765
Object is class triangle. Area is 26.765
Object is class rectangle. Area is 24.51
Object is class triangle. Area is 26.765
Object is class circle. Area is 314
Object is class circle. Area is 314
Object is class triangle. Area is 26.765
Object is class rectangle. Area is 24.51

Objects generated:
Triangles: 4
Rectangles: 4
Circles: 2
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-17 22:22 , Processed in 0.080618 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表