码迷,mamicode.com
首页 > 编程语言 > 详细

C++构造函数与析构函数

时间:2019-10-28 12:59:22      阅读:98      评论:0      收藏:0      [点我收藏+]

标签:没有   time   c++   min   end   访问   传递   函数   初始   

3.2构造函数

Part1.应用场景

在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态。

Part2.定义及代码

3.2.1构造函数、默认构造函数

1)定义:在定义对象的时候进行的数据成员设置,称为对象的初始化。

        构造函数的作用就是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态。

2)性质

    ①构造函数的函数名与类名相同;

    ② 构造函数没有返回值;

    ③通常被声明为公有函数;

    ④构造函数在对象被调用的时候自动创建。

3)默认构造函数

    调用时无需提供参数的构造函数称为默认构造函数。

    如果类中没有写构造函数,编译器会自动生成一个隐含的默认构造函数,该构造函数的参数列表和函数体皆为空。

    如果声明了构造函数(无论是否有参数),编译器都不会在为之生成隐含的构造函数。

例上题:

class Clock{
public:
   Clock(){}  //编译系统生成的隐含的默认构造函数
   ...    
};

这个构造函数不作任何事。

自己定义的构造函数:

class Clock {
public:
    Clock(int newH,int newM,int newS);//构造函数,函数名与类名相同,且没有返回值类型
    void setTime(int newH = 0, int newM = 0, int newS = 0);
    void showTime();
private:
    int hour, minute, second;
};

4)构造函数的实现

Clock::Clock(int newH, int newM, int newS) {  //自定义的构造函数带有形参,那么建立对象时就必须给出初值
    hour = newH;
    minute = newM;
    second = newS;
}

技术图片

 

 

 

自定义的构造函数带有形参,那么建立对象时就必须给出初值

int main()
{
    Clock myClock(0,0,0);//自定义的构造函数带有形参,建立对象时必须给出参数值
    myClock.showTime();
    myClock.setTime(8, 30, 30);
    myClock.showTime();
    return 0;
}

若创建对象时,没有给出参数值,就会出错。

int main()
{
    Clock myClock;//自定义的构造函数带有形参,建立对象时没有给出参数值
    myClock.showTime();
    myClock.setTime(8, 30, 30);
    myClock.showTime();
    return 0;
}

技术图片

 

 注意:

  构造函数可以直接访问类的所有数据成员,可以使内联函数,可以带有参数表,可以带默认的形参值,也可以重载。

构造函数的重载及被调用情况:

class Clock {
public:
    Clock(int newH,int newM,int newS);//带形参的构造函数
    Clock(){                                     //无参数的构造函数
         hour=newH;
         minute=newM;
         second=newS;
}
    void setTime(int newH = 0, int newM = 0, int newS = 0);
    void showTime();
private:
    int hour, minute, second;
};
int main()
{
     Clock c1(0,0,0);//调用有参数的构造函数
     Clock c2;//调用无参数的构造函数
     ...
}

 

 

 

3.2.2复制构造函数

①定义:复制构造函数是一种特殊的构造函数,具有一般构造函数的所有特性,其形参是本类的对象的引用。

②作用:使用一个已经存在的对象(由复制构造函数的参数指定),去初始化同类的一个新对象。

③隐含的复制构造函数:如果程序员没有定义类的复制构造函数,系统就会在必要时自动生成一个隐含的复制构造函数。

           其功能:把初始值对象的每个数据成员的值都复制到新建立的对象中。也可以说完成了同类对象的复制,这样的对象和原对象具有完全相同的数据成员。

④声明方法

class 类名
{
public:
      类名(形参表);//构造函数
      类名(类名&对象名);//复制构造函数
      ...
}
类名::类名(类名&对象名);
{
      函数体
}

实例:

class Point{
public:
    Point(int xx=0,int yy=0){//构造函数
         x=xx;
         y=yy;
}
    Point(Point &p);//复制构造函数
    int getX(){return x;}
    int getY(){return y;}
private:
    int x,y;
};
Point::Point(Point &p){
    x=p.x;//对象名.
    y=p.y;
    cout<<"Calling the copy constructor"<<endl;
}

⑤复制构造函数被调用的三种情况:

  a.当用类的一个对象去初始化该类的另一个对象时。

  b.如果函数的形参是类的对象,调用函数时,进行形参和实参的结合时。(只有把对象用值传递时才会调用复制构造函数,如果传递运用,则不会调用)

  c.如果函数的返回值是类的对象,函数执行完成返回调用者时。

⑥程序实例:

例4-2

#include<iostream>
using namespace std;
class Point {
public:
    Point(int xx = 0, int yy = 0) {
        x = xx;
        y = yy;
    }
    Point(Point& p);
    int getX() { return x; }
    int getY() { return y; }
private:
    int x, y;
};
//成员函数的实现
Point::Point(Point& p)
{
    x = p.x;
    y = p.y;
    cout << "Calling the copy constructor" << endl;
}
//形参为Point类对象的函数
void fun1(Point p)
{
    cout << p.getX() << endl;
}
//返回值为Point类对象的函数
Point fun2()
{
    Point a(1, 2);
    return a;
}
//主程序
int main()
{
    Point a(4, 5);//第一个对象a
    Point b = a;//情况一,用a初始化b,第一次调用复制构造函数
    cout << b.getX() << endl;
    fun1(b);//情况二,对象b作为fun1的实参,第二次调用复制构造函数
    b = fun2();//情况三,函数返回值为类对象,函数返回时调用复制构造函数
    cout << b.getX() << endl;
    return 0;
}

主函数中分别列出了3种情况下复制构造函数别调用的情况。

运行结果:

技术图片

 

 

3.3析构函数

Part1.应用场景

用来完成对象被删除前的一些清理工作,也就是专门的扫尾工作。

一般来讲,如果希望程序在对象被删除的时刻自动完成某些事情,就可以把他们写到析构函数中。

Part2.定义及代码

①作用:用来完成对象被删除前的一些清理工作,也就是专门的扫尾工作。

②调用:析构函数是在对象的生存期即将结束的时刻被自动调用的。

    他的调用完成之后,对象也就消失了,相应的内存空间也被释放。

③注意

    他的名称是由类名前面加“~”构成,没有返回值。

    和构造函数不同的是析构函数不接受任何参数,但可以是虚函数。

    如果不进行显示说明,系统会生成一个函数体为空的隐含析构函数。(函数体为空的析构函数不作任何事)

⑤例如:

class Clock {
public:
    Clock();//构造函数
    void setTime(int newH = 0, int newM = 0, int newS = 0);
    void showTime();
    ~Clock(){}  //空的内联析构函数
private:
    int hour, minute, second;
};

一般来讲,如果希望程序在对象被删除的时刻自动完成某些事情,就可以把他们写到析构函数中。

 

3.4程序实例

游泳池改造预算,Circle类

#include<iostream>
using namespace std;

const float PI = 3.141593;
const float FENCE_PRICE = 35;
const float CONCRETE_PRICE = 20;

class Circle {
public:
    Circle(float r);//构造函数
    float circumference();//计算圆的周长
    float area();//计算圆的面积
private:
    float radius;
};
//类的实现
//构造函数初始化数据成员radius
Circle::Circle(float r) {
    radius = r;
}
//计算圆的周长
float Circle::circumference() {
    return 2 * PI * radius;
}
//计算圆的面积
float Circle::area() {
    return PI * radius * radius;
}
//主函数的实现
int main()
{
    float radius;
    cout << "Emter the radius of the pool:";
    cin >> radius;
    Circle pool(radius);//游泳池边界对象
    Circle poolRim(radius + 3);//栅栏对象
    //计算栅栏造价并输出
    float fenceCost = poolRim.circumference() * FENCE_PRICE;
    cout << "Fencing Cost is $" << fenceCost << endl;
    //计算过道造价并输出
    float concreteCost = (poolRim.area() - pool.area()) * CONCRETE_PRICE;
    cout << "Concrete Cost is $" << concreteCost << endl;

    return 0;
}

技术图片

 分析:

将PI,栅栏单价,水泥单价定义为宏常量;定义类,有成员函数:计算周长,计算面积;之后是在类外声明这两个成员函数,写出周长和面积的计算公式;

最后是主函数的实现,声明两个对象,这两个对象的关系是:对象2=对象1+3;然后通过对象调用成员函数,分别乘以各自的价格即可得到造价预算。

 

C++构造函数与析构函数

标签:没有   time   c++   min   end   访问   传递   函数   初始   

原文地址:https://www.cnblogs.com/nanaa/p/11751240.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!